汇编学习--第十二天

第十一章 标志寄存器

 

 

注意!:指令集中,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

ZF PF SF
1 1 0
1 1 0
1 1 0
1 1 0
0 0 0
0 1 0
0 1 0

 

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

操作 CF OF SF ZF PF 原因
sub,al,al 0 0 0 1 1

无符号al=0

有符号al=0

mov al,10H 0 0 0 1 1

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

无符号al=10H=0001 0000b

有符号al=10H=0001 0000b

add al,90H 0 0 1 0 1

无符号al=0AH

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

mov al,80H 0 0 1 0 1

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

无符号al=80H

有符号al=-128

add al,80H 1 1 0 1 1

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

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

mov al,0FCH 1 1 0 1 1

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

无符号:al=0FCH

有符号:al=-4 

add al,05H 1 0 0 0 0

无符号:al=101H

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

mov al,7DH 1 0 0 0 0

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

无符号:al=7DH

有符号:125

add al,0BH 0 1 1 0 1

无符号: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进行进位计算步骤:

  1. 低位加低位
  2. 高位加高位,再加上低位相加的进位

 

计算 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为例

 

SF OF 结论
1 0 ah<bh
1 1

ah>bh

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

0 1

ah<bh

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

0 0 ah>bh
posted @ 2019-07-17 00:14  Hk_Mayfly  阅读(406)  评论(0编辑  收藏  举报