zoukankan      html  css  js  c++  java
  • 汇编学习--第十二天

    第十一章 标志寄存器

    注意!:指令集中,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
  • 相关阅读:
    进程Queue
    进程ID
    多进程
    queue 生产者、清费者
    让静态页面显示用户登录状态
    apache2.2 + tomcat6 整合以及集群配置整理
    linux安装rzsz
    http_load
    用Ant实现Java项目的自动构建和部署
    Openfire:安装指南
  • 原文地址:https://www.cnblogs.com/Mayfly-nymph/p/11190455.html
Copyright © 2011-2022 走看看