微机原理实验.docx
《微机原理实验.docx》由会员分享,可在线阅读,更多相关《微机原理实验.docx(44页珍藏版)》请在冰豆网上搜索。
![微机原理实验.docx](https://file1.bdocx.com/fileroot1/2023-1/29/ed5a205f-dcef-45fb-a705-4bae8c0a4707/ed5a205f-dcef-45fb-a705-4bae8c0a47071.gif)
微机原理实验
实验01a,01b,02a,02b,02c
实验01A,将FFFFH送到AX,BX,CX,DX,SI,DI,BP寄存器。
程序如下:
CODESEGMENT
ASSUMECS:
CODE
STARTPROCFAR
STT:
PUSHDS
SUBAX,AX
PUSHAX
;==============================
MOVAX,0FFFFH
MOVBX,AX
MOVCX,AX
MOVDX,AX
MOVSI,AX
MOVDI,AX
MOVBP,AX
;==============================
RET
STARTENDP
CODEENDS
ENDSTT
提示:
此程序属于“helloworld”型的入门程序,目的在于熟悉汇编编程和运行环境,以及熟悉使用DEBUG。
另外,此程序没有涉及到在内存中进行读写数据,所以不需要定义数据段。
==============================
实验01B,将FFH送到内存1000H,1001H,1002H,1003H,1004H单元中。
程序如下:
DATASEGMENT
ORG1000H
H1DB5DUP(?
)
DATAENDS
CODESEGMENT
ASSUMECS:
CODE,DS:
DATA
STARTPROCFAR
STT:
PUSHDS
SUBAX,AX
PUSHAX
;==============================
MOVAL,0FFH
MOVDI,1000H
MOVCX,5;循环5次
LP1:
MOV[DI],AL;FF放入1000H-1004H中
INCDI
DECCX
JNZLP1
;==============================
RET
STARTENDP
CODEENDS
ENDSTT
提示:
此程序由于数据少,所以完全可以不使用循环,但循环作为重要的编程指令,应熟练掌握。
注意数据段的定义方法以及程序前后基本上是固定的格式。
==============================
实验02A,编写一个加法程序,在数据段偏移地址1000H处开始,存放有两个3字节长的数据(高位对应高地址,低位对应低地址),求这两数据(十六进制数)的和,并将结果放在两数据之后,利用DEBUG调试程序,并求解:
CCBBAAH+223344H=?
CCBBAA+554433H=?
。
程序如下:
DATASEGMENT
ORG1000H
H1DB10DUP(?
)
DATAENDS
CODESEGMENT
ASSUMECS:
CODE,DS:
DATA
STARTPROCFAR
STT:
PUSHDS
SUBAX,AX
PUSHAX
;==============================
MOVSI,1000H;不带最高位进位的全加器
MOVDI,1003H
MOVBX,1006H
MOVCX,3
CLC
AA:
MOVAL,[SI]
ADCAL,[DI]
MOV[BX],AL
PUSHF;保护FR,这里其实没有必要,因为INC不会产生进位
INCSI
INCDI
INCBX
POPF
LOOPAA
MOVDL,0;最高位进位
ADCDL,0
MOVDI,1009H
MOV[DI],DL
;==============================
RET
STARTENDP
CODEENDS
ENDSTT
提示:
了解ADD及ADC的区别,并熟练使用。
注意程序中某些指令如LOOP固定搭配的寄存器CX,以及何时应该保护标志寄存器FR。
熟练使用DEBUG中的E命令进行改写内存。
==============================
实验02B,用串传送指令把A程序的数据块(被加数、加数、和)偏移地址1000H开始的区域传递到同一数据段的偏移地址为1010H开始的区域,并利用DEBUG岔开运行结果。
程序如下:
DATASEGMENT
ORG1000H
H1DB20DUP(?
)
DATAENDS
CODESEGMENT
ASSUMECS:
CODE,DS:
DATA
STARTPROCFAR
STT:
PUSHDS
SUBAX,AX
PUSHAX
;==============================
MOVAX,DS;使ES段地址与DS相同
MOVES,AX
MOVSI,1000H;不带最高位进位的全加器
MOVDI,1003H
MOVBX,1006H
MOVCX,3
CLC
AA:
MOVAL,[SI]
ADCAL,[DI]
MOV[BX],AL
PUSHF;保护FR,这里其实没有必要,因为INC不会产生进位
INCSI
INCDI
INCBX
POPF
LOOPAA
MOVDL,0;最高位进位
ADCDL,0
MOVDI,1009H
MOV[DI],DL
MOVSI,1000H;串传送
MOVDI,1010H
MOVCX,5
CLD
REPMOVSW;一次传送一个字
;==============================
RET
STARTENDP
CODEENDS
ENDSTT
提示:
此实验需要在前一个实验的基础上完成,需要做的仅仅是进行数据的串传送。
注意MOVSW用到的寄存器,包括SI,DI,CX以及最重要的ES,此程序中ES必须与DS相等,否则就不知道会传到哪儿去了。
同样可以使用MOVSB指令,一次传送一个字节,注意要传送10次。
==============================
实验02C,选作。
程序如下:
DATASEGMENT
H1DB"Theaddendsallmustbetwofigures,insufficientadds0infront.",13,10,'$'
DATAENDS
CODESEGMENT
ASSUMECS:
CODE,DS:
DATA
STARTPROCFAR
STT:
PUSHDS
SUBAX,AX
PUSHAX
;==============================
MOVAX,DATA
MOVDS,AX
LEADX,H1;打印注释:
加数和被加数都必须为两位数,不够的前面补0
MOVAH,09H
INT21H
SUBCX,CX;CX清零
SUBDX,DX;DX清零
CLC;清CF
MOVAH,1;输入第1个数
INT21H
MOVCH,AL;放入CH
SUBCH,30H;ASCII码调整
INT21H;输入第2个数
MOVCL,AL;放入CL
SUBCL,30H;ASCII码调整
MOVAH,2;打印加号
MOVDL,2BH
INT21H
MOVAH,1;输入第3个数
INT21H
MOVDH,AL;放入DH
SUBDH,30H;ASCII码调整
INT21H;输入第4个数
MOVDL,AL;放入DL
SUBDL,30H;ASCII码调整
ADDCL,DL;ASCII码个位加法
CMPCL,10;比较个位数结果是否大于10
JNCAA;大于等于10则跳至AA
ADDCH,DH;个位不向十位进位的十位加法
JMPBB
AA:
ADDCH,DH;个位向十位有进位的十位加法
ADDCH,1
SUBCL,10
BB:
MOVDL,3DH;打印等号
MOVAH,2
INT21H
CMPCH,10;比较十位数结果是否大于10
JNCCC
MOVDL,0;打印十位不向百位进位的百位=0
INT21H
JMPCCC
CC:
MOVDL,31H;打印十位向百位进位的百位=1
INT21H
SUBCH,10
CCC:
ADDCH,30H;ASCII码调整
MOVDL,CH;打印结果中的十位
INT21H
ADDCL,30H;ASCII码调整
MOVDL,CL;打印结果中的个位
INT21H
MOVAH,1;暂停
INT21H
;==============================
RET
STARTENDP
CODEENDS
ENDSTT
提示:
此程序为选作实验。
难度比较大,当然是相对咱们的水平来说。
我的这个程序没用使用进制转换,也没有使用DAA进行BCD调整,所以比较简单。
思路是这样的,程序分3块,1、输入问题,2、输出问题、3、计算问题。
首先输入使用了软件中断指令INT,功能号为1时表示从键盘输入并回显,输入字符放入了AL中。
2、输入同样使用了软件中断指令,功能号为2时表示显示输入,输出字符需要放入DL中。
使用DOS功能大大简化了自己的程序,要掌握。
调用功能号在实验册附录三中。
3、计算。
主要的问题都在计算上,因为从键盘读入的数字放到寄存器中并不是我们输入的数字,而是相应的ASCII码,所以不能直接计算或者进制转换。
使用进制转换的话有两种方法,一种是DAA调整,一种是直接转换,即除16取余的方法。
无论使用哪种方法都需要在计算前后进行ASCII到HEX和HEX到ACSII的转换。
所以相当的麻烦,所以我没有进行进制转换,而是想到ASCII也是一种BCD码,为什么不能直接计算呢,所以直接用ASCII进行计算,然后在计算后再进行ASCII调整,使其显示的结果正确。
调整的思路也比较简单,实际数字比与其对应的ASCII码小30H,所以就利用+/-30H进行调整。
需要注意的是进位的问题,不管你使用的是ADD还是ADC,它都不会进位的,因为我们使用了8位寄存器而仅放了一位数字,所以进位程序要自己编写,而且别光想着进位而忘记本位上要减去10。
程序中涉及到了ASCII码,这个是要查表的,我没有表,就问了老师加号和等号的,其他的都是用DEBUG一个一个试出来的,呵呵,见笑。
实验03A,在数据段偏移地址0100H处开始,存放0-9的平方值(构成一个表格),任给一个自然数M在0110H单元中(0<=M<=9),查表求出M的平方值,并将结果放入0111H单元。
程序如下:
DATASEGMENT
ORG0100H
H1DB00,01,04,09,16,25,36,49,64,81
ORG0110H
H2DB7,?
DATAENDS
CODESEGMENT
ASSUMECS:
CODE,DS:
DATA
STARTPROCFAR
STT:
PUSHDS
SUBAX,AX
PUSHAX
;==============================
MOVAX,DATA
MOVDS,AX
MOVSI,OFFSETH2
MOVAL,[SI]
MOVBX,OFFSETH1
XLAT
INCSI
MOV[SI],AL
;==============================
RET
STARTENDP
CODEENDS
ENDSTT
提示:
1、数据表中如果输入的是十进制数,后面不要加H。
2、理解XLAT指令的操作过程及原理,牢记该指令背后使用的寄存器:
AL和BX。
3、传送内存数据表偏移地址尽量使用OFFSET获取,避免使用硬编码,以免程序运行时发生意外错误。
4、熟练并灵活使用DEBUG的R命令和E命令,实现在不退出DEBUG的情况下查出其他的平方值。
==============================
实验03B,从内存1000H开始,建立19个自然递增然后又递减的数据串(0-9-0),用DEBUG查看运行结果。
程序如下:
DATASEGMENT
ORG1000H
H1DB20DUP(?
)
DATAENDS
CODESEGMENT
ASSUMECS:
CODE,DS:
DATA
STARTPROCFAR
STT:
PUSHDS
SUBAX,AX
PUSHAX
;==============================
MOVSI,OFFSETH1
MOVDI,OFFSETH1
ADDDI,12H
MOVAL,0
MOVCX,10
AA:
MOV[SI],AL
MOV[DI],AL
INCSI
DECDI
INCAL
LOOPAA
;==============================
RET
STARTENDP
CODEENDS
ENDSTT
提示:
该程序比较简单的一种思路是使用两次循环,第一次从0-8,循环9次,第二次从9-0,循环10次,这种方法比较好理解,但是操作比较多,本程序思路为同时从两边向中间写,从0-9,中间的9在一个单元写了两次,所以只使用了一次循环,且只循环10次。
该题比较简单,但如果循环内容复杂且耗时的话,本程序耗时基本为思路一的1/2,性能好。
实验要求掌握循环的编程方法。
==============================
实验03C,选作,在数据段偏移地址1000H处,安排部分七段LED显示码表,要求从键盘上任给一个0~F中的数,然后再屏幕上显示出其对应的码值。
七段共阴极LED显示码表见实验册P14。
程序如下:
DATASEGMENT
ORG1000H
H1DB3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,77H,7CH,39H,5EH,79H,71H
H2DB1DUP(?
)
TIPDB13,10,"TheinputnumbermustbeaHEX(0~F),presstoquit.",13,10,'$'
ERRDB13,10,"TheinputnumbermustbeaHEX(0~F).",13,10,'$'
DATAENDS
CODESEGMENT
ASSUMECS:
CODE,DS:
DATA
STARTPROCFAR
STT:
PUSHDS
SUBAX,AX
PUSHAX
;==============================
MOVAX,DATA
MOVDS,AX
LEADX,TIP;打印TIP信息
MOVAH,09H
INT21H
BEGIN:
MOVDL,13;打印换行
MOVAH,2
INT21H
MOVDL,10;打印回行首
INT21H
MOVAH,1;等待从键盘输入
INT21H
MOVSI,OFFSETH2;保护输入
MOV[SI],AL
CMPAL,27;如果按下键,跳至QUIT
JZQUIT
CALLDISPLAY0;调用DISPLAY0子程序
CALLASCII2HEX;调用ASCII2HEX子程序
CMPAL,0FFH;如果AL不等于FF(出错码)则跳至CORRECT
JNZCORRECT
LEADX,ERR;打印错误信息
MOVAH,09H
INT21H
JMPFINISH;跳至FINISH
CORRECT:
MOVBX,OFFSETH1;查表
XLAT
MOVAH,0
MOVBX,0
MOVBL,AL;分离AL的高4位和低4位,分离后AL中为高4位,BL中为低4位
ANDAL,0F0H
MOVCL,4
SHRAL,CL
ANDBL,0FH
CALLHEX2ASCII;调用HEX2ASCII
CALLDISPLAY;调用DISPLAY子程序
MOVAL,BL
CALLHEX2ASCII
CALLDISPLAY
MOVDL,72;打印字母"H"
MOVAH,2
INT21H
JMPFINISH
QUIT:
CALLESCAPE;调用ESCAPE子程序
FINISH:
JMPBEGIN
;==============================
RET
STARTENDP
ASCII2HEXPROCNEAR
CMPAL,30H;ASCII转16进制子程序
JBERROR;如果AL<0则跳至ERROR
CMPAL,39H
JBENUMBER;如果AL<=9则跳至NUMBER
CMPAL,46H
JAERROR;如果AL>F则跳至ERROR
SUBAL,07H
NUMBER:
SUBAL,30H
JMPDONE
ERROR:
MOVAL,0FFH
DONE:
RET
ASCII2HEXENDP
HEX2ASCIIPROCNEAR
CLC;16进制转ASCII子程序
DAA
ADDAL,0F0H
ADCAL,40H
RET
HEX2ASCIIENDP
DISPLAYPROCNEAR
PUSHDX;显示结果子程序
MOVDL,AL
MOVAH,2
INT21H
POPDX
RET
DISPLAYENDP
DISPLAY0PROCNEAR
PUSHAX;该子程序打印输入及":
"
PUSHDX
PUSHF
MOVDL,13
MOVAH,2
INT21H
MOVDL,10
INT21H
MOVDL,[SI];打印输入
INT21H
MOVDL,58;打印":
"
INT21H
POPF
POPDX
POPAX
RET
DISPLAY0ENDP
ESCAPEPROCNEAR
MOVAH,4CH;返回操作系统子程序
INT21H
RET
ESCAPEENDP
CODEENDS
ENDSTT
提示:
此实验为选作。
重点在与查表程序,但难点在于ASCII码与16进制的互相转换,以及怎样使用DOS子程序实现输入输出。
从键盘输入到AL的数值并不是我们所需要的数字,而是相应的ASCII码,所以输入后要转成16正确的16进制数,然后进行查表换码,输出前同样要再次转回相应的ASCII码以便计算机显示输出。
另外,学会使用子程序以简化主程序的结构。
实验04A,把BX中的“1”的个数放到AL中,并在屏幕上显示“1”的个数。
程序如下:
CODESEGMENT
ASSUMECS:
CODE
STARTPROCFAR
STT:
PUSHDS
SUBAX,AX
PUSHAX
;==============================
CLC
MOVAX,0
MOVDX,0
MOVBX,000FH
MOVCX,16
CHECK:
SHLBX,1
ADCDL,0
CMPDL,1
JZCOUNT
CONTINUE:
LOOPCHECK
JMPFINISH
COUNT:
ADDAL,1
DAA
CLC
MOVDX,0
JMPCONTINUE
FINISH:
MOVAH,0
MOVBX,0
MOVBL,AL;分离AL的高4位和低4位,分离后AL中为高4位,BL中为低4位
ANDAL,0F0H
MOVCL,4
SHRAL,CL
ANDBL,0FH
CALLHEX2ASCII;调用HEX2ASCII
CALLDISPLAY;调用DISPLAY子程序
MOVAL,BL
CALLHEX2ASCII
CALLDISPLAY
;==============================
RET
STARTENDP
HEX2ASCIIPROCNEAR
CLC;16进制转ASCII子程序
DAA
ADDAL,0F0H
ADCAL,40H
RET
HEX2ASCIIENDP
DISPLAYPROCNEAR
PUSHDX;显示结果子程序
MOVDL,AL
MOVAH,2
INT21H
POPDX
RET
DISPLAYENDP
CODEENDS
ENDSTT
提示:
该实验要求掌握将16进制数转换成BCD码和将BCD码转换成ASCII码并输出显示的方法。
需要注意的是BCD转换成ASCII码前要分离高低4位,并一位一位地显示输出。
==============================
实验04B,选作,编写程序在CRT上显示图形(图形见实验册P17)。
程序如下:
CODESEGMENT
ASSUMECS:
CODE
STARTPROCFAR
STT:
PUSHDS
SUBAX,AX
PUSHAX
;==============================
MOVBL,14H
MOVBH,1
MOVCX,0AH
LP:
PUSHBX
CALLSPACE
CALLSTAR
CALLCRLF
POPBX
DECBL
ADDBH,2
LOOPLP
;==============================
RET
STARTENDP
SPACEPROCNEAR
;打印空格子程序
PUSHCX
MOVCX,0
MOVAH,2
MOVDL,32
MOVCL,BL
LP1:
INT21H
LOOPLP1
POPCX
RET
SPACEENDP
STARPROCNEAR
;打印"*"子程序
PUSHCX
MOVCX,0
MOVDL,2AH
MOVAH,2
MOVCL,BH
LP2:
INT21H
LOOPLP2
POPCX
RET
STARENDP
CRLFPROCNEAR
;回车换行子程序
MOVDL,13
MOVAH,2
INT21H
MOVDL,10
INT21H
RET
CRLFENDP
CODEENDS
ENDSTT
提示:
该实验不难。
掌握画流程图简化编成思路的方法。
学会看流程图。
==============================
实验04C,选作,自动生成1至99BCD数并