汇编学习--第十二天

it2022-05-05  135

第十一章 标志寄存器

 

 

注意!:指令集中,add,sub,mul,div,inc,or,and等逻辑或算术运算影响标志寄存器,其他的mov,push,pop等指令对标志寄存器没有影响。

 

 

11.1 ZF标志

判断指令执行之后,结果是否为0,为0,ZF=1,不为0,ZF=0。

 

11.2 PF标志

判断指令执行之后,结果1的个数是否为偶数,偶数--PF=1,奇数--PF=0

 

11.3 SF标志

判断指令执行之后,结果是否为负,负数--SF=1,非负--SF=0

注意:无符号数,SF没有意义。

 

检测点11.1

ZFPFSF110110110110000010010

 

assume cs:code code segment start: sub al,al mov al,1 push ax pop bx add al,bl add al,10 mul al mov ax,4c0h int 21h code ends end start

 

 

 

11.4 CF标志

判断是否有向更高位的进位值,有--CF=1,无--CF=0

 

11.5 OF标志

判断溢出,操作值都是有符号数

判断是否溢出,溢出--OF=1,没有溢出--OF=0

溢出判断方法:

1.

异号相加,同号相减,不会溢出

异号相减,同号相加,可能溢出

 

2.对于两个操作值(8位

若都在范围内(-128-127),直接加减,判断是否溢出(不在范围内),实际得到的值为,无符号操作数加减,去掉进位,取补码;

若有不在范围内的,先(按有符号数)取补码,再进行加减,得到的结果判断是否溢出,实际得到的值为,无符号操作数加减,去掉进位,取补码。

 

例子:

mov al,0F0H add al,088H;0F0H=1111 0000b 088H=1000 1000b ;(0F0H)补=1001 0000b=-16 (088H)补=1111 1000b=-120 ;判断溢出:(-16)+(-120)=-136<-128-----溢出,OP=1;进位:0F0H+088H=0001 0111 1000b----进位,CF=1 ;实际值:(0F0H+088H)去掉进位,取补码=0111 1000b=120

 

mov al,98 add al,99 ;判断溢出:98+99=197>127----溢出,OP=1;进位:197=1100 0101b----无进位,CF=0;实际值:(197)补=1011 1011b=-59

 

mov al,0F0H add al,78H ;(0F0H)补=-16 ;判断溢出:(-16)+120=104<127----未溢出,OP=0 ;判断进位:0F0H+078H=0001 0110 1000b----进位,CF=1

 

检测点 11.2

操作CFOFSFZFPF原因sub,al,al00011

无符号al=0

有符号al=0

mov al,10H00011

mov指令不改变标志寄存器值

无符号al=10H=0001 0000b

有符号al=10H=0001 0000b

add al,90H00101

无符号al=0AH

有符号al=10H + (90H)补=异号相加

mov al,80H00101

mov指令不改变标志寄存器值

无符号al=80H

有符号al=-128

add al,80H11011

无符号= 100H=0001 0000 0000=0

有符号=-128+(-128)=-256<-128

mov al,0FCH11011

mov指令不改变标志寄存器值

无符号:al=0FCH

有符号:al=-4 

add al,05H10000

无符号:al=101H

有符号:-4+5=1<127 

mov al,7DH10000

 mov指令不改变标志寄存器值

无符号:al=7DH

有符号:125

add al,0BH01101

无符号:al=88H

有符号:al=125+11=136>127 

 

11.6 adc指令

格式:adc obj1,obj2

功能:obj1=obj1+obj2+CF

可以实现进位计算

assume cs:code code segment mov ax,2 mov bx,1 sub bx,ax;bx=ffffh,CF=1 adc ax,1;ax=2+1+1=4 mov ax,4c00h int 21h code ends end

 

adc进行进位计算步骤:

低位加低位高位加高位,再加上低位相加的进位

 

计算 1EF000H+201000H,结果放在ax(高16位),bx(低16位)中

assume cs:code code segment mov ax,1EH mov bx,1000H add bx,0F000H adc ax,20H mov ax,4c00h int 21h code ends end

 

 

计算1E F000 1000H + 20 1000 1EF0H,结果放在ax(最高位),bx(次高位),cx(低位)中

assume cs:code code segment mov ax,1EH mov bx,0F000H mov cx,1000H add cx,1EF0H adc bx,1000H adc ax,20H mov ax,4c00h int 21h code ends end

 

编写一个子程序,对两个128位数据进行相加。

128位=16字节=8字

思路:分别用一个16位寄存器指向这两个数据的低16位,相加之后,结果保存到第一个数中,跳到高位继续相加(加上进位),循环到最高位结束相加。

assume cs:code,ds:data data segment dd 12345678h,11021121h,21415161h,71819202h,11223242h,42627282h,83031323h,13536383h data ends code segment start: mov ax,data mov ds,ax mov si,0 mov di,10h call add128 mov ax,4c00h int 21h add128: push ax push cx push si push di sub ax,ax mov cx,8 main: mov ax,[si] adc ax,[di] mov [si],ax add si,2 add di,2 loop main ok: pop di pop si pop cx pop ax ret code ends end start

 

11.7 sbb指令

sbb和adc相反,进行的是,obj1=obj1-obj2-CF

 

11.8 cmp指令

 cmp指令相当于减法指令sub,但并不保存结果,它只对标志寄存器产生影响。

assume cs:code code segment mov ax,8 mov bx,3 cmp ax,bx mov ax,4c00h int 21h code ends end

 

CMP对于CF(sign flag),不能通过CF为0或1,判断运算应该得到的结果的正负,通过前面溢出,我们知道运算应该得到结果和实际结果有可能异号。因此我们应该通过,两个数值进行cmp操作后的CF和OF,来判断两个数值的大小关系,和应该得到结果的正负。

以cmp ah,bh为例

 

SFOF结论10ah<bh11

ah>bh

如果因为溢出,导致实际结果为负,那么逻辑上真正结果应该为正

01

ah<bh

如果因为溢出,导致实际结果为正,那么逻辑上真正结果应该为负

00ah>bh

转载于:https://www.cnblogs.com/Mayfly-nymph/p/11190455.html


最新回复(0)