资源描述
微机实验报告曾东明实验一 输出字符一、实验目的1通过这个简单的例子熟悉在微机上建立、汇编、链接和运行8086/8088汇编语言程序的过程。2掌握字符的显示方法。3学习DOS系统功能调用。二、实验内容输出字符A,程序流程图如图1-1所示。图1-1输出字符A程序流程图源程序如下: CODE SEGMENT ASSUME CS:CODE MOV DL, A MOV AH, 2 INT 21H MOV AH, 4CH INT 21H CODE ENDS END三、实验设备PC机一台,MASM汇编程序 四、实验步骤1用记事本将源程序输入,并存盘。注意:源程序是用汇编语言语句编写的程序,并不能为机器所识别。源程序的扩展名为.ASM2用宏汇编程序将.ASM源程序汇编成机器码的目标文件(OBJ文件)3用LINK程序产生执行文件(EXE文件)4执行程序实验结果: 五、心得体会第一次经历了汇编语言的上机过程,对在计算机上进行汇编语言程序设计的步骤不是很熟悉,对命令提示符的一些操作命令不懂,后来查阅了一些资料,比如可以在window7下按住shift,点击鼠标右键,在弹出的窗口里就可以打开命令提示符了。 六、思考题1请说出一个完整的汇编程序从编写到运行所需的步骤。(1)用编辑程序建立ASM源程序文件(2)用宏汇编程序将.ASM源程序汇编成机器码的目标文件(OBJ文件)(3)用LINK程序产生执行文件(EXE文件)(4)在DOS命令行直接键入文件名执行该文件2修改源程序,改变屏幕显示的内容。修改的源程序:CODE SEGMENT ASSUME CS:CODE MOV DL, D MOV AH, 2 INT 21H MOV AH, 4CH INT 21H CODE ENDS END实验二数据的显示实验一、实验目的1掌握屏幕上显示各种进制数据的方法。2掌握将内存中的二进制数转换为十进制、十六进制数的方法。 3学会子程序的编写、调用及数据传递方法。二、实验内容1把BX中的无符号二进制数转换成十进制数,在屏幕上显示出来。 2把BX中的带符号二进制数转换成十进制数,在屏幕上显示出来。3求一个数据块(由10个单字节的无符号数组成)中的最大元素,并将结果以十进制数的形式在屏幕上显示出来。4求一个数据块(由20个单字节的带符号数组成)中的正数之和(和不超过字)和负数之和(和不超过字),并在屏幕上用十进制数的形式分别显示出两个和。5将寄存器BX中的二进制数转换成十六进制数,并在屏幕上显示出来。从高到低依次取出4位二进制数变为ASCII码输出即可。三、实验设备:PC机一台、masm汇编程序 四、实验步骤:依照前面介绍的方法,对每一个实验内容对应的程序进行编辑、编译、连接和运行,直到达到实验要求。1实验内容1(1)实验内容1的流程图,如图所示:(2) 实验内容1的程序: CODE SEGMENT ASSUME CS: CODE DEC_DIV MACRO MOV AX, BX MOV DX, 0 DIV CX MOV BX, DX MOV DL, AL ADD DL, 30H MOV AH, 2 INT 21H ENDM START: MOV BX, 0FFFH MOV CX, 1000 DEC_DIV MOV CX, 100 DEC_DIV MOV CX, 10 DEC_DIV MOV CX, 1 DEC_DIV MOV AH, 4CH INT 21H CODE ENDS END START(3)实验结果: 2. 实验内容2(1) 实验容1的程序:DATA SEGMENTA DW 1000B DW 100C DW 10D DW 1DATA ENDSCODE SEGMENT ASSUME CS: CODE,DS:DATA START: MOV AX,DATA MOV DS,AX MOV BX, 0FFEFH ;-0017的补码是0FFEFH OR BX,BX JNS NEXT NEG BX AND BH,7FH MOV DL,2DH MOV AH,2 INT 21H NEXT: MOV SI,OFFSET A CALL DEC_DIV MOV SI,OFFSET B CALL DEC_DIV MOV SI,OFFSET C CALL DEC_DIV MOV SI,OFFSET D CALL DEC_DIV MOV AH, 4CH INT 21H DEC_DIV PROC NEAR MOV CX, SI MOV AX, BX MOV DX, 0 DIV CX MOV BX, DX MOV DL, AL ADD DL, 30H MOV AH, 2 INT 21H RET DEC_DIV ENDP CODE ENDS END START(2)实验结果:3实验内容3(1)实验内容3的流程图,如图所示:(2)实验3的程序:DATA SEGMENT BLOCK DB 1,0,5,7,10,30,100,127,90,80 RESULT DB ?,? BUF DB MAX IS:$DATA ENDSCODE SEGMENT ASSUME CS:CODE,DS:DATA BEGIN PROC FAR MOV AX, DATA MOV DS, AX MOV CX, 9 LEA SI, BLOCK MOV AL, SI X1: INC SI CMP AL, SI JAE X2 MOV AL, SI X2: LOOP X1 MOV RESULT, AL MOV DX, OFFSET BUF MOV AH, 9 INT 21H MOV BL,RESULT CBW MOV CX, 1000 CALL DEC_DIV MOV CX, 100 CALL DEC_DIV MOV CX, 10 CALL DEC_DIV MOV CX, 1 CALL DEC_DIV MOV AH, 4CH INT 21H DEC_DIV PROC NEAR MOV AX, BX MOV DX, 0 DIV CX MOV BX, DX MOV DL, AL ADD DL, 30H MOV AH, 2 INT 21H RET DEC_DIV ENDP BEGIN ENDP CODE ENDS END BEGIN(3) 实验3的运行结果:4实验内容4(1)实验内容4的流程图,如图所示: (2) 实验内容4程序:DATA SEGMENT BLOCK DB -1,-2,-3,-4,-5,-6,-7,-8,-9,-10 DB 11,12,13,14,15,16,17,18,19,20 POSIT DW ? NEGAT DW ? BUF1 DB POSIT:$ BUF2 DB NEGAT:$ DATA ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA START PROC MOV AX, DATA MOV DS, AX MOV BX, OFFSET BLOCK MOV SI, 0 MOV DI, 0 MOV CX, 20 X1: MOV AL, BX CBW CMP AX, 0 JGE X3 ADD DI, AX JMP X2 X3: ADD SI, AX X2: INC BX LOOP X1 MOV POSIT, SI MOV NEGAT, DI MOV DX, OFFSET BUF1 MOV AH, 9 INT 21H MOV BX,POSIT MOV CX, 1000 CALL DEC_DIV MOV CX, 100 CALL DEC_DIV MOV CX, 10 CALL DEC_DIV MOV CX, 1 CALL DEC_DIV MOV DL,0AH MOV AH,2 INT 21H MOV DX, OFFSET BUF2 MOV AH, 9 INT 21H MOV BX,NEGAT NEG BX AND BH,01111111B MOV DL,2DH;显示负号 MOV AH,2 INT 21H MOV CX, 1000 CALL DEC_DIV MOV CX, 100 CALL DEC_DIV MOV CX, 10 CALL DEC_DIV MOV CX, 1 CALL DEC_DIV MOV AH, 4CH INT 21H DEC_DIV PROC NEAR MOV AX, BX MOV DX, 0 DIV CX MOV BX, DX MOV DL, AL ADD DL, 30H MOV AH, 2 INT 21H RET DEC_DIV ENDP CODE ENDS END START (3)实验结果: 5. 实验内容5(1)实验内容5的流程图,如图所示: 图2-4 内容5流程图(2)实验内容5的源程序,参考如下: CODE SEGMENT ASSUME CS:CODE BINHEX PROC FAR MOV CH,4 MOV BX,1000 ROTATE: MOV CL,4 ROL BX,CL MOV DL,BL AND DL,0FH ADD DL,30H CMP DL,3AH JL OUTPUT ADD DL,7 OUTPUT: MOV AH,2 INT 21H DEC CH JNE ROTATE MOV DL,H MOV AH,2 INT 21H MOV AH,4CH INT 21H BINHEX ENDP CODE ENDS END BINHEX(3)实验结果:5、 心得体会实验内容1:宏定义必须先定义,后调用,自己刚开始时把宏定义放在调用的后面,导致程序出错。看了生产的LIST给出的源程序和目标程序,发现每个宏调用处,通过宏扩展,宏体中的指令的机器代码被插入到宏调用处,不节省内存单元,但相对于子程序,简化了源程序。实验内容2:刚开始的时候给BX寄存器送负值,比如-17,我写成了1000 0000 0001 0001即 MOV BX,8011H,后来发现显示出来的数不是-17。经过思考,懂得原来负数的表示要用补码,下面是两种LIST 文件里对应地方的目标程序和源程序,可以看出转化为目标程序的时候,用补码表示。0000 BB FFEF START: MOV BX, -0011H0000 BB FFEF START: MOV BX, 0FFEFH 实验内容3:求一个数据块中最大元素的时候,把数据块中的第一个元素AL中,并通过循环把其余的元素和AL比较,如果新元素较大的话就取代原来的元素放到AL中。比较完成后,把最大的元素放到预先为其保留的地址中,注意要控制的次数CX,是数据块的个数减一。LOOP 标号 功能相当于 DEC CXJNZ 标号实验内容4:回车和换行的效果不一样。显示字符串的时候要注意用$。因为要将正数与负数分别累加,这时候需要分支,而分支的条件有很多种,比如跟0比较大小,比如通过提取符合位来判断,只要能正确实现分支都可以。实验内容5:16位的二进制数,4位一组可以显示为4位十六进制数,从高到低依次取出4位二进制数变成ASC码输出即可。要注意ASICC代码中,1-9的ASICC代码要比1-9的二进制值大30H,A-F的ASICC代码要比1-9的二进制值大37H,所以对不同的四位二进制,要加个判断分支,才能找到相应得ASICC代码。六、思考题1请总结显示寄存器或者内存中的十进制和十六进制数据的方法。十进制显示的方法:先判断是正数负数,是负数要把它转化成负数的绝对值,并在前面加一个负号。把BX中的数按位由高到低转化成十进制数,即依次对其除以10000、1000、100、10、1,将获得的商放到 DL中,加30H变成ASC码,调用DOS系统中断INT 21H的2号功能显示出来;对于每一位十进制数的获得和显示,实验通过编制子程序DEC_DIV并不断调用来实现。十六进制的显示方法:16位的二进制数,4位一组可以显示为4位十六进制数,从高到低依次取出4位二进制数变成ASC码输出即可,可以用循环左移的指令POL,循环左移四位,并提取这四位。2 请总结子程序编写、调用及参数传递的要点。子程序定义格式如下:过程名 PROC NEAR/FAR RET 过程名 ENDP 调用的时候用 CALL 过程名参数传递有三种方法:(1)通过寄存器传递参数,这种方式适合于传递参数较少的一些简单程序。 (2) 通过地址表传递参数地址,这种方式适合于参数较多的情况,但要求事先建立一个用来传送参数的地址。(3)通过堆栈传递参数。为了利用堆栈传递参数,必须在主程序中调用子程序之前的地方,把这些参数压入堆栈后利用在子程序中的指令从堆栈弹出而取得参数。 同样,要从子程序传递回调用程序的参数也被压入堆栈内,然后由主程序中的指令把这些参数从堆栈中取出。3修改源程序,改变屏幕显示的内容。1:2:3:4:5: 实验三 从键盘上输入数据实验一、实验目的1掌握从键盘上输入数据的方法。2键盘上输入的是ASCII字符,掌握如何将ASCII字符转换为机内数字。二、实验内容1从键盘上输入一个十进制数(065535),转换成二进制数并放入寄存器BX中。2从键盘上输入065535范围的一个十进制数,在屏幕上显示出相PC机一台、masm汇编程序 三、实验设备PC机一台、masm汇编程序 四、实验步骤:依照上次实验步骤,对每一个实验内容对应的程序进行编辑、编译、连接和运行,直到达到实验要求。1. 实验内容1的程序:CODE SEGMENT ASSUME CS:CODE START PROC CALL DECBIN MOV DL,0DH MOV AH,2 INT 21H CALL XIANSHI MOV AH,4CH INT 21H START ENDP DECBIN PROC NEAR MOV CX,10 MOV BX,0 LOP1: MOV AH,1 INT 21H CMP AL,30H JL EXIT CMP AL,39H JG EXIT SUB AL,30H MOV AH,00H XCHG AX,BX MUL CX ADD BX,AX JMP LOP1 EXIT: RET DECBIN ENDPXIANSHI PROC NEAR LP1: MOV CX,10000 CALL DEC_DIV MOV CX,1000 CALL DEC_DIV MOV CX,100 CALL DEC_DIV MOV CX,10 CALL DEC_DIV MOV CX,1 CALL DEC_DIV RET XIANSHI ENDP DEC_DIV PROC NEAR MOV AX,BX MOV DX,0 DIV CX MOV BX,DX MOV DL,AL ADD DL,30H MOV AH,2 INT 21H RET DEC_DIV ENDP CODE ENDS END START (2) 运行结果:输入11111后,程序显示如图所示:2. 实验内容2(1) 实验内容2的程序:STACK SEGMENT DB 20 DUP(?)STACK ENDSCODE SEGMENT ASSUME CS:CODE,SS:STACK START PROC MOV AX,STACK MOV SS,AX CALL DECBIN CALL XIANSH MOV DL,0AH MOV AH,2 INT 21H MOV CH,4 CALL ROTATE MOV AH,4CH INT 21H START ENDP XIANSHI PROC NEAR PUSH BX LP1: MOV CX,10000 CALL DEC_DIV MOV CX,1000 CALL DEC_DIV MOV CX,100 CALL DEC_DIV MOV CX,10 CALL DEC_DIV MOV CX,1 CALL DEC_DIV POP BX RET XIANSHI ENDP DEC_DIV PROC NEAR MOV AX,BX MOV DX,0 DIV CX MOV BX,DX MOV DL,AL ADD DL,30H MOV AH,2 INT 21H RET DEC_DIV ENDP DECBIN PROC NEAR MOV CX,10 MOV BX,0 LOP1: MOV AH,1 INT 21H CMP AL,30H JL EXIT CMP AL,39H JG EXIT SUB AL,30H MOV AH,00H XCHG AX,BX MUL CX ADD BX,AX JMP LOP1 EXIT: RET DECBIN ENDPROTATE PROC LOP2: MOV CL,4 ROL BX,CL MOV DL,BL AND DL,0FH ADD DL,30H CMP DL,3AH JL OUTPUT;小于转移 ADD DL,7 OUTPUT: MOV AH,2 INT 21H DEC CH JNE LOP2 MOV DL,H MOV AH,2 INT 21H RET ROTATE ENDP CODE ENDS END START(2) 运行结果:输入00010,显示结果如图3-4所示:5、 心得体会在写实验二的时候,调用子程序的地方比较多,可是调用子程序的时候,没有对寄存器的数据进行保护,导致程序的执行结果不正确,后来用压栈会保护寄存器里的数据,并用出栈来恢复寄存器的数据,使程序的执行结果正确。六、思考题1请总结从键盘上输入字符的方法。从键盘上输入一个十进制数(065535),转换成二进制数并放入寄存器BX中。对于输入的字符,先判断它是不是19的数字字符,若不是,直接跳出循环,若是的话,将ASC码转化成对应数值并存到AX中,对于下一个输入的数值,判断完成后,通过将AX和BX内容交换并将AX中的数*10,再累加实现。2 请总结将二进制数转换为十六进制数并显示的方法。16位的二进制数,4位一组可以显示为4位十六进制数,从高到低依次取出4位二进制数变成ASC码输出即可,可以用循环左移的指令POL,循环左移四位,并提取这四位。3修改源程序,改变屏幕显示的内容。实验内容1:输入22222,显示实验内容2:输入12,显示实验四字符串的显示实验一、实验目的:掌握字符串的显示方法。二、实验内容:1. 在内存中存有一个字符串,以0为结尾,程序开始输出“HELLO”然后等待从键盘输入一个字符,在字符串中寻找该字符,若找到,输出“yes”;若找不到,输出“no”,然后再输入下一个字符。2. 实验内容的程序是一个无限循环的程序,若按“ESC”键,让程序推出循环,使系统返回DOS。已知“ESC”键的键值是1BH。按照上面的要求对实验内容的程序进行修改,然后再重新汇编、链接和运行。三、实验设备:PC机一台、masm汇编程序四、实验步骤:1. 实验内容1(1)实验内容1程序:DATA SEGMENT STR1 DB HELLO,0DH,0AH,$ STR2 DB 20H,YES,0DH,0AH,$ STR3 DB 20H,NO,0DH,0AH,$ STR4 DB 1 2 3 0 4 5 A B a=! ?,00H DATA ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA START PROC FAR MOV AX,DATA MOV DS,AX MOV DX,OFFSET STR1 MOV AH,9 INT 21H LOOP1: MOV AH,1 INT 21H MOV BX,OFFSET STR4 GON: MOV AH,BX CMP AH,0 JZ NO INC BX CMP AH,AL JNZ GON MOV DX,OFFSET STR2 GO: MOV AH,9 INT 21H JMP LOOP1 NO: MOV DX,OFFSET STR3 JMP GO START ENDP CODE ENDS END START(2) 运行结果2、 实验内容2(1) 实验内容2程序:DATA SEGMENT STR1 DB HELLO,0DH,0AH,$ STR2 DB 20H,YES,0DH,0AH,$ STR3 DB 20H,NO,0DH,0AH,$ STR4 DB 1 2 3 0 4 5 A B a=! ?,00H DATA ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA START PROC FAR MOV AX,DATA MOV DS,AX MOV DX,OFFSET STR1 MOV AH,9 INT 21H LOOP1: MOV AH,1 INT 21H CMP AL,1BH JZ EXIT MOV BX,OFFSET STR4 GON: MOV AH,BX CMP AH,0 JZ NO INC BX CMP AH,AL JNZ GON MOV DX,OFFSET STR2 GO: MOV AH,9 INT 21H JMP LOOP1 NO: MOV DX,OFFSET STR3 JMP GO EXIT: MOV AH, 4CH INT 21H START ENDP CODE ENDS END START(2) 运行结果:5、 心得体会通过这次实验,掌握了字符算的显示方法。该程序要用到DOS系统功能调用的9号子程序,9号子程序的功能是在屏幕上输出一个字符串,字符串要以字符“$”做为结尾符,但“$”在屏幕上不显示。六、思考题1请总结字符串的显示方法。该程序要用到DOS系统功能调用的9号子程序,9号子程序的功能是在屏幕上输出一个字符串,字符串要以字符“$”做为结尾符,但“$”在屏幕上不显示。调用号子程序的格式是:MOV DX,字符串起始地址(入口参数)MOV AH,9 INT 21H号子程序遇到 “0DH”处理成回车;遇到 “0AH”处理成换行;遇到 “20H”处理成空格。2 巩固汇编语言分支程序设计的方法。 许多实际问题并不能设计成顺序程序,需要根据不同的条件作出不同的处理。把不同的处理方法编制成各自的处理程序段,运行时由机器根据不同的条件自动作出选择判断,绕过某些指令,仅执行相应的处理程序段。按这种方式编制的程序,称之为分支程序。 分支程序是机器利用改变标志位的指令和转移指令来实现的。 转移指令有JMP和Jcc两类。前者是无条件转移指令,后者是条件转移指令。
展开阅读全文