汇编学习(四)——算术运算程序
(一)跳转指令
一、无条件跳转指令(不管标志寄存器,执行到这句直接跳转)
1、段内直接跳转指令
(1)指令格式:
JMP SHORT short_label; IP<--IP+DB,即代码直接跳转到此地址为
JMP near_label; IP<--IP+D16 基准的相应的地址中
(2)其实就是GOTO语句,不同的就是他跳转只能以跳转地址与目前地址的偏差量来进行跳转。
2、段间直接跳转语句
(1)指令格式:
JMP far_label; IP<-标号的偏移地址,CS<--标号的段地址
若指定的目标标号在另一个段中,就成为了段间跳转指令
(2)一个demo
CODE SEGMENT
ASSUME CS:CODE
START: 1~3条JMP指令没有指定标号的类型(FAR,NEAR),汇编程序默认为段内的标号,并根据标号的距离大小自动处理成SHORT或者NEAR类型
JMP START; 被翻译成段内短跳转
JMP EXIT; 被翻译成段内直接跳转,但因为跳转的距离较短,所以又自动改为段内短跳转,所以加了个NOP
JMP EXIT1; 被翻译成段内直接跳转
JMP SHORT EXIT; 被翻译成段内短跳转
JMP NEAR PTR EXIT; 被翻译成段内直接跳转,但因为跳转的距离较短,所以又自动改为段内短跳转,所以加了个NOP
JMP FAR PTR EXIT; 被翻译成段间直接跳转,单因为是段内的跳转且距离短,所以又自动改为段内短跳转,所以加了3个NOP
JMP FAR PTR EXIT2; 被翻译成段间直接跳转
EXIT:
MOV AH,4CH
INT 21H
ORG 200H ;其中ORG 200H是一个伪指令,指定段内偏移地址的伪指令,即接下来的指令从偏移地址200H开始存放
EXIT1:
MOV AH,4CH
INT 21H
CODE ENDS
CODE1 SEGMENT
ASSUME CS:CODE1
EXIT2:
MOV AH,4CH
INT 21H
CODE1 ENDS
END START
3、段内间接跳转指令:
(1)指令格式:
JMP reg16 ;IP<--reg16
JMP mem16 ;IP<--mem16
此指令的操作数必须是一个16位的通用寄存器或者16位的存储单元,功能是将此16位操作数赋给IP而实现跳转。
(2)一个demo:
设BX=1234H,DS=1000H,(11234H)= 5678H
若执行JMP BX,则IP=1234H
若执行JMP [BX],则IP=5678H
4、段间间接跳转指令
(1)指令格式:
JMP mem32;IP<--[mem32],CS<--[mem32+2]
(2)一个demo:
例如,设BX=1234H,DS=1000H,(11234H)=5678H,(11236H)=9ABCH,
若执行JMP [BX],则IP=5678H,CS=9ABCH,即程序跳到段地址为9ABCH,偏移地址为5678H的地址处继续执行。
二、条件跳转指令
1、指令的一般格式:
Jccc short_label; 若条件成立,则IP<--IP+D8,否则顺序执行
2、指令格式中的“ccc”是1~3个字母,指明判断的条件,目的地址是段内的短标号,但是范围只有D8,所以超出了合法范围,都会报错
3、所有指令汇总
三、循环控制指令
1、为了方便循环程序的设计,8086设计了一组共用4条用CX作为循环计数的循环控制指令,也正是由于这个原因,我们把CX成为计数寄存器。循环控制指令一般都要先对循环计数CX自动减1,然后在判断CX是否为0
2、CX不为0循环指令
(1)指令格式:
LOOP short_label; CX<--CX-1,若CX不等于0,则跳转,否则顺序执行
(2)图示:
3、CX不为0且相等循环指令
(1)指令格式:
LOOPE short_label; CX<--CX-1,若CX不等于0,且ZF=1,则跳转,否则顺序执行
LOOPZ short_label;
所以只要用ZF=1,则就会提前结束循环
(2)图示:
4、CX不为0且不等循环指令
(1)指令格式:
LOOPNE short_label; CX<--CX-1,若CX不等于0且ZF=0,则跳转,否则顺序执行 LOOPNZ short_label
5、CX为0跳转指令
(1)指令格式:
JCXZ short_label;若CX=0,则跳转,否则顺序执行
CX=0时跳转,一般在循环体中需要跳出循环时使用
(二)算术运算指令
一、二进制运算指令
1、不带CF的加/减指令
(1)指令格式:
ADD dst,src; dst<--dst+src
SUB dst,src; dst<--dst-src
段寄存器不能使用,对6个条件标志位均有影响
2、带CF的加/减指令
(1)指令格式:
ADC dst,src; dst<--dst+src+CF
SBB dst,src; dst<--dst-src-CF
(2)注意点
一条带CF的加/减指令实际上涉及两个CF,参加加/减计算的是前一个字节计算后影响的CF,本次计算后影响的CF留下给下一字节计算。
3、比较指令
(1)指令格式:
CMP dst,src; dst<—src
(2)ZF标志位变化意义:
ZF = 1,则两个数字相等,ZF = 0,则不相等。
(3)CF标志位意义:无符号数判断大小:
CF = 0,则被减数大于或等于减数,若CF 0 1,则相反。
(4)OF,SF标志位意义:有符号数判断大小:
A、
OF = 0, SF = 0,则被减数大于等于减数。 SF = 1,则被减数小于减数 OF = 1, SF = 0,则被减数大于减数 SF = 0,则被减数小于减数
B、OF和SF相同,被减数大于等于减数,OF和SF不同,被减数小于等于减数
4、加1/减1指令
(1)指令格式:
INC dst ; dst<--dst+1 DEC dst; dst<-dst-1
能够使用的操作数是reg和mem,8位或者16位都可以
(2)功能:主要用于循环程序中对地址指令修改和对循环次数进行计数。
5、求补指令
(1)指令格式:
NEG dst; dst<--0-dst
能够使用的操作数也是reg和mem,8或者16位均可以。
(2)作用:
A、求带符号负数的绝对值
B、对带符号正数操作,得到绝对值相等的负数
6、乘法指令
(1)指令格式:
MUL src; AX<-AL*8位src或 DX,AX<--AX*16位src ;无符号数乘法指令,能做8位*8位,16位*16位的乘法运算,但乘法指令只能指定一个源操作数作为乘数,可以是
;8位或者16位的reg或者mem。若操作数是16位,则乘积在DX(高16位)和AX(低16位中)
IMUL src; AX<-AL*8位src或 DX,AX<--AX*16位src ; 有符号数乘法指令
(2)相关注意点
乘法指令对OF和CF标志位有影响,其他标志位不确定
A、无符号数,若高8/16位等于0则OF=CF=0,否则OF=CF=1
B、有符号数,若高8/16位的积的高16位DX是低16位AX的符号扩张,则OF=CF=0,OF=CF=1。
7、除法指令
(1)指令格式:
DIV src; AX/8位src,AL<--商,AH<--余数 ; DX(高)、AX(低)/16位src,AX<--商,DX<--余数 IDIV src; AX/8位src,AL<--商,AH<--余数 ; DX(高)、AX(低)/16位src,AX<--商,DX<--余数
(2)相关注意点:
出发指令对标志位的影响是不确定的
8、符号扩展指令
(1)指令格式:
CBW;若AL最高位为1,则AH<--0FFH,否则AH<--0 CWD;若AX最高位为1,则DX<--0FFFFH,否则DX<--0
(2)使用地方:
一条除法指令只能做16位除以8位,或32位除以16位的运算,若要进行8位除以8位,或16位除以16位的运算,则必须先把被除数从8位扩展到16位,或16位扩展到32位。一般是配合带符号除法
9、二进制运算指令的使用:
(1)一般只能带符号之间进行运算,不带符号之间进行运算
(2)但是要是1个带符号和一个无符号数进行乘法或者除法运算也是可以实现的:
A、求带符号数的绝对值
B、用无符号数乘或除指令进行此绝对值与无符号数的乘或除运算
C、将无符号数转换成带符号数
二、BCD码调整
1、压缩型BCD码加法调整指令:
(1)指令格式:
DAA;若AL的低4位>9或AF = 1,则AL<—AL + 06H,AF<--1
;若AL的高4位>9或CF = 1,则AL<—AL + 06H,CF<--1
(2)使用注意点:
DAA指令必须跟在一条以AL为目的操作数的ADC或着ADD指令之后,且相加的数必须是合法的压缩型BCD码
2、非压缩性BCD码加法调整指令
(1)指令格式:
AAA;若AL的低4位>9或AF=1,则AL<--AL+06H,CF<--AF<--1,AH<—AH - 1,AL高4位清0
(2)使用注意点:
AAA指令必须跟在一条以AL为目的操作数的ADC或着ADD指令之后,且相加的数必须是合法的压缩型BCD码
3、压缩型BCD码减法调整指令
(1)指令格式:
DAS;若AL的低4位>9或AF = 1,则AL<—AL - 06H,AF<--1
;若AL的高4位>9或CF = 1,则AL<—AL - 06H,CF<--1
(2)使用注意点:
DAS指令必须跟在一条以AL为目的操作数的SUB或着SBB指令之后,且相减的数必须是合法的压缩型BCD码
4、非压缩型BCD码减法调整指令
(1)指令格式:
AAS;若AL的低4位 > 9或AF = 1,则AL<—AL - 06H,CF<--AF<--1,AH<—AH - 1,AL高4位清0
(2)使用注意点:
DAS指令必须跟在一条以AL为目的操作数的SUB或着SBB指令之后,且相减的数必须是合法的压缩型BCD码
5、非压缩型BCD码乘法调整指令
(1)指令格式:
AAM; AL<—AH * 0AH + AL,AH = 0
(2)使用注意点:
AAM指令必须跟在一条8位乘8位指令之后,且相乘的数必须是合法的压缩型BCD码
6、非压缩型BCD吗除法调整指令
(1)指令格式:
AAD; AL<—AH / 0AH,AH<--商,AL<—余数
(2)使用注意点:
AAD指令必须放在一条16位除以8位指令之前,且相除的数必须是合法的压缩型BCD码
(三)多字节加/减运算程序
一、多字节加法程序流程图
二、程序如下:多字节加法
DATA SEGMENT ;数据段 DATA1 DB 4 DUP(?) DATA2 DB 4 DUP(?) DATA3 DB 5 DUP(?) DATA ENDS CODE SEGMENT ;代码段 ASSUME CS:CODE,DS:DATA START: MOV AX,DATA MOV DS,AX MOV SI,OFFSET DATA1 ;取地址 MOV DI,OFFSET DATA2 MOV BX,OFFSET DATA3 MOV CX,DATA2-DATA1 CLC NEXT: ;循环做加法 MOV AL,[SI] ADC AL,[DI] NOP MOV [BX],AL INC SI INC DI INC BX LOOP NEXT MOV AL,0 ;处理最后的进位 ADC AL,0 MOV [BX],AL MOV AH,4CH INT 21H CODE ENDS END START
三、基本调试方法:
1、显示和修改内存中的数据
(1)使用U命令可以看到反汇编得到的程序
从中可以得到数据段的地址是076A
(2)使用D命令可以看数据
(3)使用E命令进行修改
2、断点运行程序
(1)使用G命令可以使程序执行一段规定的长度。
3、修改程序指令
使用A命令,再键入要写入的命令即可。
(四)多字节除法程序
一、除法指令的除法程序
1、程序流程图如下:
2、程序如下:
DATA SEGMENT DATA1 DB 4 DUP(?) ;被除数 DATA2 DB 1 DUP(?) ;除数 DATA3 DB 5 DUP(?) ;商 DATA ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA START: MOV AX,DATA ;初始化 MOV DS,AX LEA SI,DATA1 ;取地址 LEA DI,DATA3 MOV CX,DATA2-DATA1 ;确定循环次数 MOV AH,0 NEXT: MOV AL,[SI] ;取被除数的一字节 NOP NOP DIV DATA2 MOV [DI],AL ;存储 INC SI INC DI LOOP NEXT MOV DATA3+4,AH ;对余数进行的处理 MOV AH,4CH INT 21H CODE ENDS END START
二、被除数左移法的除法程序
1、程序流图
2、程序如下:
DATA SEGMENT DATA1 DB 4 DUP(?) DATA2 DB ? DATA3 DB ? DATA ENDS
CODE SEGMENT ASSUME CS:CODE,DS:DATA START: MOV AX,DATA MOV DS,AX MOV AL,0 MOV CH,8*LENGTH DATA1
NEXT1: LEA SI,DATA2-1 MOV CL,DATA2-DATA1 CLC NEXT2: MOV AH,[si] adc ah,[si] mov [si],ah dec si dec cl jnz next2 adc al,al JC NEXT4 cmp al,data2 jc next3 NEXT4: sub al,data2 inc data2-1 next3: dec ch jnz next1 mov data3,al mov ah,4ch int 21h code ends end start