微机原理加法程序
- 格式:doc
- 大小:513.59 KB
- 文档页数:4
实验一 加法程序一.实验目的学习并掌握数据传送和算术运算指令的用法。
编写多位十进制数相加程序。
二.实验内容将两个多位十进制数28056,47193相加,并在屏幕上显示加数、被加数、和。
要求两个操作数均以ASCII 码形式各自顺序存放在DA TA1和DA TA2内存单元中,并将结果送回DA TA1处(低位在前,高位在后)。
三.程序流程图程序流程如图2.1所示。
两操作数在内存中存放的情况如图2.2所示。
四、实验步骤(1)进入DOS 环境,如果计算机操作系统是在DOS 环境下,则直接进入下一步即可。
如果计算机操作系统是在Windows 环境下,则打开“开始”菜单,选“运行”项,在“打开”栏中输入“CMD ”,点击“确定”按钮,进入DOS 环境;(2)将设计好的汇编语言程序用编辑器编辑;EDIT *. ASM ,其中* 号代表程序名,为任意1~8个字符,扩展名 .ASM 不可缺省。
进入编辑状态,输入汇编语言源程序,完成后,同时按“Alt+F ”按钮,打开文件菜单,选择“Save ”选项存盘,随后,选择“Exit ”选项,退出编辑状态;(3)对源程序进行汇编链接;(4)执行并调试可执行文件。
进入DOS 全屏模式,运行可执行文件*.EXE ,调试器运行和调试可执行文件*.EXE 。
五、参考程序SHOWMACRO B;宏定义MOV DL , B ;B 为要显示字符的ASCII 码MOV AH , 02HINT21H;2号功能调用,在屏幕上显示一个字符图2.1 十进制数相加程序流程图 33H 39H 31H 37H 34H36H 35H 30H38H32H存储器DATA1DATA1图2.2 数据在内存中的存放情况ENDMDATA SEGMENT ;数据段DATA1 DB 33H,39H,31H,37H,34H ;被加数47193的ASCII码(倒序存放)DATA2 DB 36H,35H,30H,38H,32H ;加数28056的ASCII码(倒序存放)DATA3 DB '——— ',0DH,0AH,'$ 'DATA ENDSSTACK SEGMENT STACK ;堆栈段STA DB 20 DUP (?)TOP EQU LENGTH STASTACK ENDSCODE SEGMENT ;代码段ASSUME CS:CODE,DS:DATA,SS:STACK,ES:DATASTART:MOV AX,DATA ;初始化,取段基址MOV DS,AXMOV AX,STACKMOV SS,AXMOV AX,TOPMOV SP,AXMOV SI,OFFSET DA TA2 ;取DATA2(加数)的偏移地址MOV BX,05 ;设置地址指针,BX=5 (加数为5位)SHOW 20H ;宏调用,显示“空格”(ASCII码为20H)CALL DISPL ;调显示子程序SHOW 0DH ;宏调用,“回车”SHOW 0AH ;宏调用,“换行”MOV SI,OFFSET DA TA1 ;取DATA1(被加数)的偏移地址MOV BX,05 ;设置地址指针,BX=5 (被加数为5位)SHOW 2BH ;宏调用,显示“+”(ASCII码为2BH)CALL DISPL ;调显示子程序SHOW 0DH ;宏调用,“回车”SHOW 0AH ;宏调用,“换行”MOV CL,7 ;CL=7,显示7个“-”,构成直线S1:SHOW 2DH ;宏调用,显示“-”(ASCII码为2DH)LOOP S1 ;CX-1→CX,CX≠0,转到标号S1SHOW 0DHSHOW 0AHMOV SI,OFFSET DA TA1 ;取DATA1(被加数)的偏移地址MOV DI,OFFSET DA TA2 ;取DATA2(加数)的偏移地址CALL ADDA ;调加法程序MOV SI,OFFSET DA TA1 ;取DATA1的偏移地址,显示两数之和SHOW 20HMOV BX,05 ;BX=5,设置地址指针CALL DISPL ;调显示子程序MOV AX,4C00H ;返回DOSINT 21HDISPL PROC NEAR ;显示子程序DS1:SHOW [SI+BX-1] ;宏调用,倒序显示数据DEC BX ;BX←BX-1JNZ DS1 ;BX≠0,转到标号DS1,继续显示数据RETDISPL ENDPADDA PROC NEAR ;加法子程序MOV DX,SI ;DATA1的偏移地址传送给DXMOV BP,DI ;DATA2的偏移地址传送给BPMOV BX,05 ;BX=5,设置地址指针AD1:SUB BYTE PTR [SI+BX-1],30H ;将ASCII码转化为十六进制数,并存入DA TA1 SUB BYTE PTR [DI+BX-1],30H ;将ASCII码转化为十六进制数,并存入DA TA2 DEC BX ;BX←BX-1JNZ AD1 ;BX≠0,转到标号AD1,继续转换MOV SI,DX ;SI←DATA1的偏移地址MOV DI,BP ;DI←DATA2的偏移地址MOV CX,05 ;CX=5,设置计数常数CLC ;清除进位表示,CF=0AD2:MOV AL,[SI] ;AL←DATA1中的低位数MOV BL,[DI] ;BL←DATA1中的低位数ADC AL,BL ;带进位相加AAA ;十进制调整MOV [SI],AL ;将结果保存到DATA1中INC SI ;指向下一位INC DILOOP AD2 ;CX-1→CX,CX≠0,转到标号AD2,继续加法MOV SI,DX ;SI←DATA1的偏移地址MOV DI,BP ;DI←DATA2的偏移地址MOV BX,05 ;BX=5,设置地址指针AD3:ADD BYTE PTR [SI+BX-1],30H ;将十六进制转化为ASCII码ADD BYTE PTR [DI+BX-1],30HDEC BX ;BX←BX-1JNZ AD3 ;BX≠0,转到标号AD3,继续转换RETADDA ENDPCODE ENDSEND START六、实验结果七、思考题不改变数据段DATA1和DATA2的内容,如何将加数与被加数分别由28056和47193变成65082和39174,并且相加。
MYDATA SEGMENTNUM DB 4 DUP(0)SUM DB 3 DUP(0)MYDATA ENDSSTACK SEGMENTDW 200 DUP(?)STACK ENDSMYCODE SEGMENTASSUME CS:MYCODE,DS:MYDATA,ES:MYDATA,SS:STACK0SOFTDLY PROCPUSH BXPUSH CXMOV BL,50DELAY:MOV CX,3800WAITA:LOOP WAITADEC BLJNZ DELAYPOP CXPOP BXRETSOFTDLY ENDPSAOMIAO PROCPUSH AXPUSH BXPUSH CXPUSH DXMOV DX,0600H ;设置8255的PA端口地址MOV AL,00H ;使行输出全为0OUT DX,ALLP1: MOV DX,0602H ; 设置8255 PB端口地址IN AL,DX ; 读入列线值AND AL,0FH ; 屏蔽高位无关位CMP AL,0FH ; 列线值是否全为1JZ LP1 ; 若列线值全为1,则无键按下,等待按键 MOV CX,2000H ; 设置循环次数DELAY1:LOOP DELAY1 ; 若有按键按下,延迟20MS,清除抖动 IN AL,DXAND AL,0FHCMP AL,0FHJZ LP1LP2:MOV BL,4 ; 行扫描次数送BLMOV BH,4 ; 列扫描次数送BHMOV AL,0FEH ; 设置行扫描初值MOV CH,0FFH ; 设置起始键号为FFHLP3:MOV DX,0600H ; 设置8255PA端口地址OUT DX,AL ; 输出扫描初值ROL AL,1 ; 修改扫描码,为扫描下一行做准备MOV AH,AL ; 保持修改后的扫描码MOV DX,0602H ; 设置8255PB端口地址IN AL,DX ; 读入列值AND AL,0FH ; 屏蔽高位无关位CMP AL,0FH ; 查列线是否全为1JNZ LP4 ; 有,则转去找该列线ADD CH,BH ; 无,则修改键号指向该行末列键号MOV AL,AH ; 取回扫描码DEC BL ; 行值减1JNZ LP3 ; 行末查完转下一行JMP LP2 ; 重新开始扫描键盘LP4:INC CH ;键号加1,指向本行首列键号RCR AL,1 ; 右移一位JC LP4MOV [SI],CH ;键号送入[SI]中INC SIPOP DXPOP CXPOP BXPOP AXRETSAOMIAO ENDPSTART:MOV AX,MYDATA ;主程序开始MOV DS,AXMOV ES,AXMOV SI,OFFSET NUMMOV DI,OFFSET SUMMOV DX,0606H ;8255控制口地址MOV AL,82H ;方式控制字,PA口方式0输入(行),PB口方式0输入(列) OUT DX,ALMOV CX ,2L1:CALL SAOMIAO ;输入第一个数CALL SOFTDLYLOOP L1MOV CX,2L2:CALL SAOMIAO ;输入第二个数CALL SOFTDLYLOOP L2MOV CX,2MOV SI,OFFSET NUMCLCL3:MOV AL,[SI+1] ;开始进行加法运算ADC AL,[SI+3]AAAMOV [DI+2],ALDEC DIDEC SILOOP L3MOV AH,0 ;防止溢出,保存进位ADC AH,0MOV [DI+2],AHMOV DI,OFFSET SUML4:MOV DX,0604H ;送8255的PC口地址MOV AH,[DI+1]ROL AH,4MOV AL,[DI+2]ADD AL,AHOUT DX,AL ;将十位,个位输出到PC口使LED灯显示 MOV AL,[DI]ROL AL,4MOV DX,0600HOUT DX,AL ;将百位输出到PA口高4位使LED灯显示 MOV CX,20L5:CALL SOFTDLY ;延迟2秒后清零LOOP L5MOV AX,0OUT DX,AXMOV DX,0604HOUT DX,AXJMP STARTMYCODE ENDSEND START。
1. 加法运算指令和调正指令ADD,ADC,INC,AAA,DAA(1)不带进位的加法运算指令ADDADD指令完成两个操作数相加,并将结果保存在目的操作数中。
指令格式:ADD OPRD1, OPRD2功能:操作数OPRD1与OPRD2相加,结果保存在OPRD1中。
说明:操作数OPRD1可以是累加器AL或AX,也可以是其它通用寄存器或存储器操作数,OPRD2可以是累加器、其它通用寄存器或存储器操作数,还可以是立即数。
OPRD1和OPRD2不能同时为存储器操作数,不能为段寄存器。
ADD指令的执行对全部6个状态标志位产生影响。
例如:ADD AL, BL ;AL+BL结果存回AL中。
ADD AX, SI ;AX+SI结果存回AX中。
ADD BX, 3DFH ;BX+03DFH结果存回BX中。
ADD DX, DA TA[BP+SI] ;DX与内存单元相加,结果存回DX中。
ADD BYTE PTR[DI], 30H ;内存单元与30H相加,结果存回内存单元中。
ADD [BX], AX ;内存单元[BX]与AX相加,结果存回[BX]中。
ADD [BX+SI], AL ;内存单元与AL相加,结果存回内存单元中。
【例题3-3】求D9H与6EH的和,并注明受影响的标志位状态。
MOV AL, 0D9HMOV BL, 6EHADD AL, BL结果AL=47H,标志位CF=1,PF=1,AF=1,ZF=0,SF=0,OF=0(2)带进位的加法运算指令ADCADC指令完成两个操作数相加之后,再加上Flags的进位标志CF。
CF的值可能为1或0。
指令格式:ADD OPRD1, OPRD2功能:操作数OPRD1与OPRD2相加后,再加上CF的值,结果保存在OPRD1中。
说明:对操作数的要求与ADD指令一样。
例如:ADC AL, BLADC AX, BXADC [DI], 30HADC指令主要用于多字节数的加法运算,以保证低位向高位的进位被正确接收。
MODEL SMALLCode SegmentAssume CS:Code,DS:codeCR equ 000DHLF equ 000AHKBBack equ 0008H; -------------------------------------; 功能:显示指定地址(Str_Addr)的字符串; 入口:; Str_Addr=字符串地址(要求在数据段); 用法: Output Str_Addr; 用法举例:Output PromptStrOutput MACRO Str_Addrlea dx,Str_Addrmov ah,9int 21hEndM; ----------------------------------功能:输出一个字符; 入口:dl=要显示的字符Output_Chr proc Nearpush axmov ah,02hint 21hpop axretOutput_Chr endp; --------------功能:输出回车换行Output_CTLF proc Nearpush axpush dxmov ah,02hmov dl,0dhint 21hmov dl,0ahint 21hpop dxpop axretOutput_CTLF endp; --------------功能:取光标位置; 入口:无; 出口:DH=行号,DL=列号GetCursor Proc NearPUSH AXPUSH BXPUSH CXXOR BX,BXMOV AH,3INT 10HMOV Cursor_Row,DHMOV Cursor_Col,DLPOP CXPOP BXPOP AXRETCursor_Row DB ?Cursor_Col DB ?GetCursor EndP; ---------------revolver(39629840) 9:44:07postmessage 发送ctrl+x 组合键,有谁会的啊大叔(42947111) 9:44:17功能:置光标位置; 入口:Cursor_Row=行坐标; Cursor_Col: 列坐标)SetCursor Proc NearPUSH CXPUSH BXPUSH AXMOV DH,Cursor_RowMOV DL,Cursor_ColXOR BX,BXMOV AH,2INT 10HPOP AXPOP BXPOP CXRETSetCursor EndP; ---------------------功能:键盘输入一个指定位数的十进制数字,将其转换成二进制数并保存在指定的内存单元。
实验一 加法程序
一.实验目的
学习并掌握数据传送和算术运算指令的用法。
编写多位十进制数相加程序。
二.实验内容
将两个多位十进制数28056,47193相加,并在屏幕上显示加数、被加数、和。
要求两个操作数均以ASCII 码形式各自顺序存放在DA TA1和DA TA2内存单元中,并将结果送回DA TA1处(低位在前,高位在后)。
三.程序流程图
程序流程如图2.1所示。
两操作数在内存中存放的情况如图2.2所示。
四、实验步骤
(1)进入DOS 环境,如果计算机操作系统是在DOS 环境下,则直接进入下一步即可。
如果计算机操作系统是在Windows 环境下,则打开“开始”菜单,选“运行”项,在“打开”栏中输入“CMD ”,点击“确定”按钮,进入DOS 环境;
(2)将设计好的汇编语言程序用编辑器编辑;
EDIT *. ASM ,其中* 号代表程序名,为任意1~8个字符,扩展名 .ASM 不可缺省。
进入编辑状态,输入汇编语言源程序,完成后,同时按“Alt+F ”按钮,打开文件菜单,选择“Save ”选项存盘,随后,选择“Exit ”选项,退出编辑状态;
(3)对源程序进行汇编链接;
(4)执行并调试可执行文件。
进入DOS 全屏模式,运行可执行文件*.EXE ,调试器运行和调试可执行文件*.EXE 。
五、参考程序
SHOW
MACRO B
;宏定义
MOV DL , B ;B 为要显示字符的ASCII 码
MOV AH , 02H
INT
21H
;2号功能调用,在屏幕上显示一个字符
图2.1 十进制数相加程序流程图 33H 39H 31H 37H 34H
36H 35H 30H
38H
32H
存储器
DATA1
DATA1
图2.2 数据在内存中的存放情况
ENDM
DATA SEGMENT ;数据段
DATA1 DB 33H,39H,31H,37H,34H ;被加数47193的ASCII码(倒序存放)DATA2 DB 36H,35H,30H,38H,32H ;加数28056的ASCII码(倒序存放)DATA3 DB '——— ',0DH,0AH,'$ '
DATA ENDS
STACK SEGMENT STACK ;堆栈段
STA DB 20 DUP (?)
TOP EQU LENGTH STA
STACK ENDS
CODE SEGMENT ;代码段
ASSUME CS:CODE,DS:DATA,SS:STACK,ES:DATA
START:MOV AX,DATA ;初始化,取段基址
MOV DS,AX
MOV AX,STACK
MOV SS,AX
MOV AX,TOP
MOV SP,AX
MOV SI,OFFSET DA TA2 ;取DATA2(加数)的偏移地址
MOV BX,05 ;设置地址指针,BX=5 (加数为5位)
SHOW 20H ;宏调用,显示“空格”(ASCII码为20H)
CALL DISPL ;调显示子程序
SHOW 0DH ;宏调用,“回车”
SHOW 0AH ;宏调用,“换行”
MOV SI,OFFSET DA TA1 ;取DATA1(被加数)的偏移地址
MOV BX,05 ;设置地址指针,BX=5 (被加数为5位)
SHOW 2BH ;宏调用,显示“+”(ASCII码为2BH)
CALL DISPL ;调显示子程序
SHOW 0DH ;宏调用,“回车”
SHOW 0AH ;宏调用,“换行”
MOV CL,7 ;CL=7,显示7个“-”,构成直线
S1:SHOW 2DH ;宏调用,显示“-”(ASCII码为2DH)LOOP S1 ;CX-1→CX,CX≠0,转到标号S1
SHOW 0DH
SHOW 0AH
MOV SI,OFFSET DA TA1 ;取DATA1(被加数)的偏移地址
MOV DI,OFFSET DA TA2 ;取DATA2(加数)的偏移地址
CALL ADDA ;调加法程序
MOV SI,OFFSET DA TA1 ;取DATA1的偏移地址,显示两数之和
SHOW 20H
MOV BX,05 ;BX=5,设置地址指针
CALL DISPL ;调显示子程序
MOV AX,4C00H ;返回DOS
INT 21H
DISPL PROC NEAR ;显示子程序
DS1:SHOW [SI+BX-1] ;宏调用,倒序显示数据
DEC BX ;BX←BX-1
JNZ DS1 ;BX≠0,转到标号DS1,继续显示数据
RET
DISPL ENDP
ADDA PROC NEAR ;加法子程序
MOV DX,SI ;DATA1的偏移地址传送给DX
MOV BP,DI ;DATA2的偏移地址传送给BP
MOV BX,05 ;BX=5,设置地址指针
AD1:SUB BYTE PTR [SI+BX-1],30H ;将ASCII码转化为十六进制数,并存入DA TA1 SUB BYTE PTR [DI+BX-1],30H ;将ASCII码转化为十六进制数,并存入DA TA2 DEC BX ;BX←BX-1
JNZ AD1 ;BX≠0,转到标号AD1,继续转换
MOV SI,DX ;SI←DATA1的偏移地址
MOV DI,BP ;DI←DATA2的偏移地址
MOV CX,05 ;CX=5,设置计数常数
CLC ;清除进位表示,CF=0
AD2:MOV AL,[SI] ;AL←DATA1中的低位数
MOV BL,[DI] ;BL←DATA1中的低位数
ADC AL,BL ;带进位相加
AAA ;十进制调整
MOV [SI],AL ;将结果保存到DATA1中
INC SI ;指向下一位
INC DI
LOOP AD2 ;CX-1→CX,CX≠0,转到标号AD2,继续加法
MOV SI,DX ;SI←DATA1的偏移地址
MOV DI,BP ;DI←DATA2的偏移地址
MOV BX,05 ;BX=5,设置地址指针
AD3:ADD BYTE PTR [SI+BX-1],30H ;将十六进制转化为ASCII码
ADD BYTE PTR [DI+BX-1],30H
DEC BX ;BX←BX-1
JNZ AD3 ;BX≠0,转到标号AD3,继续转换
RET
ADDA ENDP
CODE ENDS
END START
六、实验结果
七、思考题
不改变数据段DATA1和DATA2的内容,如何将加数与被加数分别由28056和47193变成65082和39174,并且相加。
答:源程序不变将
DATA1 DB 33H,39H,31H,37H,34H
DATA2 DB 36H,35H,30H,38H,32H 后加上
DATA4 DB 37H,34H,31H,39H,33H
DATA5 DB 32H,38H,30H,35H,36H
并将全部DATA1和DA TA2全部改成DATA4和DA TA5就可以实现。