1、微机原理实验实验01a,01b,02a,02b,02c实验01A,将FFFFH送到AX,BX,CX,DX,SI,DI,BP寄存器。程序如下:CODE SEGMENTASSUME CS:CODESTART PROC FARSTT:PUSH DS SUB AX,AX PUSH AX;= MOV AX,0FFFFH MOV BX,AX MOV CX,AX MOV DX,AX MOV SI,AX MOV DI,AX MOV BP,AX;= RETSTART ENDPCODE ENDSEND STT提示:此程序属于“hello world”型的入门程序,目的在于熟悉汇编编程和运行环境,以及熟悉使用DEB
2、UG。另外,此程序没有涉及到在内存中进行读写数据,所以不需要定义数据段。=实验01B,将FFH送到内存1000H,1001H,1002H,1003H,1004H单元中。程序如下:DATA SEGMENTORG 1000HH1 DB 5 DUP(?)DATA ENDSCODE SEGMENTASSUME CS:CODE,DS:DATASTART PROC FARSTT:PUSH DS SUB AX,AX PUSH AX;= MOV AL,0FFH MOV DI,1000H MOV CX,5 ;循环5次LP1:MOV DI,AL ;FF放入1000H-1004H中 INC DI DEC CX JN
3、Z LP1;= RETSTART ENDPCODE ENDSEND STT提示:此程序由于数据少,所以完全可以不使用循环,但循环作为重要的编程指令,应熟练掌握。注意数据段的定义方法以及程序前后基本上是固定的格式。=实验02A,编写一个加法程序,在数据段偏移地址1000H处开始,存放有两个3字节长的数据(高位对应高地址,低位对应低地址),求这两数据(十六进制数)的和,并将结果放在两数据之后,利用DEBUG调试程序,并求解:CCBBAAH+223344H=?CCBBAA+554433H=?。程序如下:DATA SEGMENTORG 1000HH1 DB 10 DUP(?)DATA ENDSCODE
4、 SEGMENTASSUME CS:CODE,DS:DATASTART PROC FARSTT:PUSH DS SUB AX,AX PUSH AX;= MOV SI,1000H ;不带最高位进位的全加器 MOV DI,1003H MOV BX,1006H MOV CX,3 CLCAA: MOV AL,SI ADC AL,DI MOV BX,AL PUSHF ;保护FR,这里其实没有必要,因为INC不会产生进位 INC SI INC DI INC BX POPF LOOP AA MOV DL,0 ;最高位进位 ADC DL,0 MOV DI,1009H MOV DI,DL;= RETSTART
5、ENDPCODE ENDSEND STT提示:了解ADD及ADC的区别,并熟练使用。注意程序中某些指令如LOOP固定搭配的寄存器CX,以及何时应该保护标志寄存器FR。熟练使用DEBUG中的E命令进行改写内存。=实验02B,用串传送指令把A程序的数据块(被加数、加数、和)偏移地址1000H开始的区域传递到同一数据段的偏移地址为1010H开始的区域,并利用DEBUG岔开运行结果。程序如下:DATA SEGMENTORG 1000HH1 DB 20 DUP(?)DATA ENDSCODE SEGMENTASSUME CS:CODE,DS:DATASTART PROC FARSTT:PUSH DS S
6、UB AX,AX PUSH AX;= MOV AX,DS ;使ES段地址与DS相同 MOV ES,AX MOV SI,1000H ;不带最高位进位的全加器 MOV DI,1003H MOV BX,1006H MOV CX,3 CLCAA: MOV AL,SI ADC AL,DI MOV BX,AL PUSHF ;保护FR,这里其实没有必要,因为INC不会产生进位 INC SI INC DI INC BX POPF LOOP AA MOV DL,0 ;最高位进位 ADC DL,0 MOV DI,1009H MOV DI,DL MOV SI,1000H ;串传送 MOV DI,1010H MOV
7、CX,5 CLD REP MOVSW ;一次传送一个字;= RETSTART ENDPCODE ENDSEND STT提示:此实验需要在前一个实验的基础上完成,需要做的仅仅是进行数据的串传送。注意MOVSW用到的寄存器,包括SI,DI,CX以及最重要的ES,此程序中ES必须与DS相等,否则就不知道会传到哪儿去了。同样可以使用MOVSB指令,一次传送一个字节,注意要传送10次。=实验02C,选作。程序如下:DATA SEGMENTH1 DB The addends all must be two figures, insufficient adds 0 in front.,13,10,$DATA
8、 ENDSCODE SEGMENTASSUME CS:CODE,DS:DATASTART PROC FARSTT:PUSH DS SUB AX,AX PUSH AX;= MOV AX,DATA MOV DS,AX LEA DX,H1 ;打印注释:加数和被加数都必须为两位数,不够的前面补0 MOV AH,09H INT 21H SUB CX,CX ;CX清零 SUB DX,DX ;DX清零 CLC ;清CF MOV AH,1 ;输入第1个数 INT 21H MOV CH,AL ;放入CH SUB CH,30H ;ASCII码调整 INT 21H ;输入第2个数 MOV CL,AL ;放入CL S
9、UB CL,30H ;ASCII码调整 MOV AH,2 ;打印加号 MOV DL,2BH INT 21H MOV AH,1 ;输入第3个数 INT 21H MOV DH,AL ;放入DH SUB DH,30H ;ASCII码调整 INT 21H ;输入第4个数 MOV DL,AL ;放入DL SUB DL,30H ;ASCII码调整 ADD CL,DL ;ASCII码个位加法 CMP CL,10 ;比较个位数结果是否大于10 JNC AA ;大于等于10则跳至AA ADD CH,DH ;个位不向十位进位的十位加法 JMP BBAA: ADD CH,DH ;个位向十位有进位的十位加法 ADD
10、CH,1 SUB CL,10BB: MOV DL,3DH ;打印等号 MOV AH,2 INT 21H CMP CH,10 ;比较十位数结果是否大于10 JNC CC MOV DL,0 ;打印十位不向百位进位的百位=0 INT 21H JMP CCCCC: MOV DL,31H ;打印十位向百位进位的百位=1 INT 21H SUB CH,10CCC:ADD CH,30H ;ASCII码调整 MOV DL,CH ;打印结果中的十位 INT 21H ADD CL,30H ;ASCII码调整 MOV DL,CL ;打印结果中的个位 INT 21H MOV AH,1 ;暂停 INT 21H;= RE
11、TSTART ENDPCODE ENDSEND STT提示:此程序为选作实验。难度比较大,当然是相对咱们的水平来说。我的这个程序没用使用进制转换,也没有使用DAA进行BCD调整,所以比较简单。思路是这样的,程序分3块,1、输入问题,2、输出问题、3、计算问题。首先输入使用了软件中断指令INT,功能号为1时表示从键盘输入并回显,输入字符放入了AL中。2、输入同样使用了软件中断指令,功能号为2时表示显示输入,输出字符需要放入DL中。使用DOS功能大大简化了自己的程序,要掌握。调用功能号在实验册附录三中。3、计算。主要的问题都在计算上,因为从键盘读入的数字放到寄存器中并不是我们输入的数字,而是相应的
12、ASCII码,所以不能直接计算或者进制转换。使用进制转换的话有两种方法,一种是DAA调整,一种是直接转换,即除16取余的方法。无论使用哪种方法都需要在计算前后进行ASCII到HEX和HEX到ACSII的转换。所以相当的麻烦,所以我没有进行进制转换,而是想到ASCII也是一种BCD码,为什么不能直接计算呢,所以直接用ASCII进行计算,然后在计算后再进行ASCII调整,使其显示的结果正确。调整的思路也比较简单,实际数字比与其对应的ASCII码小30H,所以就利用+/-30H进行调整。需要注意的是进位的问题,不管你使用的是ADD还是ADC,它都不会进位的,因为我们使用了8位寄存器而仅放了一位数字,
13、所以进位程序要自己编写,而且别光想着进位而忘记本位上要减去10。程序中涉及到了ASCII码,这个是要查表的,我没有表,就问了老师加号和等号的,其他的都是用DEBUG一个一个试出来的,呵呵,见笑。实验03A,在数据段偏移地址0100H处开始,存放0-9的平方值(构成一个表格),任给一个自然数M在0110H单元中(0=M=9),查表求出M的平方值,并将结果放入0111H单元。程序如下:DATA SEGMENTORG 0100HH1 DB 00,01,04,09,16,25,36,49,64,81ORG 0110HH2 DB 7,?DATA ENDSCODE SEGMENTASSUME CS:COD
14、E,DS:DATASTART PROC FARSTT:PUSH DS SUB AX,AX PUSH AX;= MOV AX,DATA MOV DS,AX MOV SI,OFFSET H2 MOV AL,SI MOV BX,OFFSET H1 XLAT INC SI MOV SI,AL;= RETSTART ENDPCODE ENDSEND STT提示:1、数据表中如果输入的是十进制数,后面不要加H。2、理解XLAT指令的操作过程及原理,牢记该指令背后使用的寄存器:AL和BX。3、传送内存数据表偏移地址尽量使用OFFSET获取,避免使用硬编码,以免程序运行时发生意外错误。4、熟练并灵活使用DEB
15、UG的R命令和E命令,实现在不退出DEBUG的情况下查出其他的平方值。=实验03B,从内存1000H开始,建立19个自然递增然后又递减的数据串(0-9-0),用DEBUG查看运行结果。程序如下:DATA SEGMENTORG 1000HH1 DB 20 DUP(?)DATA ENDSCODE SEGMENTASSUME CS:CODE,DS:DATASTART PROC FARSTT:PUSH DS SUB AX,AX PUSH AX;= MOV SI,OFFSET H1 MOV DI,OFFSET H1 ADD DI,12H MOV AL,0 MOV CX,10AA: MOV SI,AL M
16、OV DI,AL INC SI DEC DI INC AL LOOP AA ;= RETSTART ENDPCODE ENDSEND STT提示:该程序比较简单的一种思路是使用两次循环,第一次从0-8,循环9次,第二次从9-0,循环10次,这种方法比较好理解,但是操作比较多,本程序思路为同时从两边向中间写,从0-9,中间的9在一个单元写了两次,所以只使用了一次循环,且只循环10次。该题比较简单,但如果循环内容复杂且耗时的话,本程序耗时基本为思路一的1/2,性能好。实验要求掌握循环的编程方法。=实验03C,选作,在数据段偏移地址1000H处,安排部分七段LED显示码表,要求从键盘上任给一个0F中
17、的数,然后再屏幕上显示出其对应的码值。七段共阴极LED显示码表见实验册P14。程序如下:DATA SEGMENTORG 1000HH1 DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,77H,7CH,39H,5EH,79H,71HH2 DB 1 DUP(?)TIP DB 13,10,The input number must be a HEX (0F), press to quit.,13,10,$ERR DB 13,10,The input number must be a HEX (0F).,13,10,$DATA ENDSCODE SEGMENTAS
18、SUME CS:CODE,DS:DATASTART PROC FARSTT:PUSH DS SUB AX,AX PUSH AX;= MOV AX,DATA MOV DS,AX LEA DX,TIP ;打印TIP信息 MOV AH,09H INT 21H BEGIN: MOV DL,13 ;打印换行 MOV AH,2 INT 21H MOV DL,10 ;打印回行首 INT 21H MOV AH,1 ;等待从键盘输入 INT 21H MOV SI,OFFSET H2 ;保护输入 MOV SI,AL CMP AL,27 ;如果按下键,跳至QUIT JZ QUIT CALL DISPLAY0 ;调用
19、DISPLAY0子程序 CALL ASCII2HEX ;调用ASCII2HEX子程序 CMP AL,0FFH ;如果AL不等于FF(出错码)则跳至CORRECT JNZ CORRECT LEA DX,ERR ;打印错误信息 MOV AH,09H INT 21H JMP FINISH ;跳至FINISH CORRECT: MOV BX,OFFSET H1 ;查表 XLAT MOV AH,0 MOV BX,0 MOV BL,AL ;分离AL的高4位和低4位,分离后AL中为高4位,BL中为低4位 AND AL,0F0H MOV CL,4 SHR AL,CL AND BL,0FH CALL HEX2A
20、SCII ;调用HEX2ASCII CALL DISPLAY ;调用DISPLAY子程序 MOV AL,BL CALL HEX2ASCII CALL DISPLAY MOV DL,72 ;打印字母H MOV AH,2 INT 21H JMP FINISHQUIT:CALL ESCAPE ;调用ESCAPE子程序FINISH: JMP BEGIN;= RETSTART ENDPASCII2HEX PROC NEAR CMP AL,30H ;ASCII转16进制子程序 JB ERROR ;如果AL0则跳至ERROR CMP AL,39H JBE NUMBER ;如果ALF则跳至ERROR SUB
21、AL,07HNUMBER: SUB AL,30H JMP DONEERROR: MOV AL,0FFHDONE: RETASCII2HEX ENDPHEX2ASCII PROC NEAR CLC ;16进制转ASCII子程序 DAA ADD AL,0F0H ADC AL,40H RETHEX2ASCII ENDPDISPLAY PROC NEAR PUSH DX ;显示结果子程序 MOV DL,AL MOV AH,2 INT 21H POP DX RETDISPLAY ENDPDISPLAY0 PROC NEAR PUSH AX ;该子程序打印输入及: PUSH DX PUSHF MOV DL
22、,13 MOV AH,2 INT 21H MOV DL,10 INT 21H MOV DL,SI ;打印输入 INT 21H MOV DL,58 ;打印: INT 21H POPF POP DX POP AX RETDISPLAY0 ENDPESCAPE PROC NEAR MOV AH,4CH ;返回操作系统子程序 INT 21H RETESCAPE ENDPCODE ENDSEND STT提示:此实验为选作。重点在与查表程序,但难点在于ASCII码与16进制的互相转换,以及怎样使用DOS子程序实现输入输出。从键盘输入到AL的数值并不是我们所需要的数字,而是相应的ASCII码,所以输入后要转
23、成16正确的16进制数,然后进行查表换码,输出前同样要再次转回相应的ASCII码以便计算机显示输出。另外,学会使用子程序以简化主程序的结构。实验04A,把BX中的“1”的个数放到AL中,并在屏幕上显示“1”的个数。程序如下:CODE SEGMENTASSUME CS:CODESTART PROC FARSTT:PUSH DS SUB AX,AX PUSH AX;= CLC MOV AX,0 MOV DX,0 MOV BX,000FH MOV CX,16 CHECK: SHL BX,1 ADC DL,0 CMP DL,1 JZ COUNTCONTINUE: LOOP CHECK JMP FINI
24、SHCOUNT: ADD AL,1 DAA CLC MOV DX,0 JMP CONTINUE FINISH: MOV AH,0 MOV BX,0 MOV BL,AL ;分离AL的高4位和低4位,分离后AL中为高4位,BL中为低4位 AND AL,0F0H MOV CL,4 SHR AL,CL AND BL,0FH CALL HEX2ASCII ;调用HEX2ASCII CALL DISPLAY ;调用DISPLAY子程序 MOV AL,BL CALL HEX2ASCII CALL DISPLAY ;= RETSTART ENDPHEX2ASCII PROC NEAR CLC ;16进制转AS
25、CII子程序 DAA ADD AL,0F0H ADC AL,40H RETHEX2ASCII ENDPDISPLAY PROC NEAR PUSH DX ;显示结果子程序 MOV DL,AL MOV AH,2 INT 21H POP DX RETDISPLAY ENDPCODE ENDSEND STT提示:该实验要求掌握将16进制数转换成BCD码和将BCD码转换成ASCII码并输出显示的方法。需要注意的是BCD转换成ASCII码前要分离高低4位,并一位一位地显示输出。=实验04B,选作,编写程序在CRT上显示图形(图形见实验册P17)。程序如下:CODE SEGMENTASSUME CS:CO
26、DESTART PROC FARSTT:PUSH DS SUB AX,AX PUSH AX;= MOV BL,14H MOV BH,1 MOV CX,0AHLP: PUSH BX CALL SPACE CALL STAR CALL CRLF POP BX DEC BL ADD BH,2 LOOP LP;= RETSTART ENDPSPACE PROC NEAR;打印空格子程序 PUSH CX MOV CX,0 MOV AH,2 MOV DL,32 MOV CL,BLLP1:INT 21H LOOP LP1 POP CX RETSPACE ENDPSTAR PROC NEAR;打印*子程序 PUSH CX MOV CX,0 MOV DL,2AH MOV AH,2 MOV CL,BHLP2:INT 21H LOOP LP2 POP CX RETSTAR ENDPCRLF PROC NEAR;回车换行子程序 MOV DL,13 MOV AH,2 INT 21H MOV DL,10 INT 21H RETCRLF ENDPCODE ENDSEND STT提示:该实验不难。掌握画流程图简化编成思路的方法。学会看流程图。=实验04C,选作,自动生成1至99BCD数并
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1