zoukankan      html  css  js  c++  java
  • 汇编笔记_第十一章


    title: 汇编笔记_第十一章
    date: 2018-12-30 14:00:51
    tags:

    • 笔记
      categories:
    • 汇编语言

    标志寄存器

    标志寄存器的作用:

    • 用来存储相关指令的某些执行结果

    • 用来为CPU执行相关指令提供行为依据

    • 用来控制CPU的相关工作方式

    • 标志寄存器由16位,按位起作用,0,2,4,6,7,8,9,10,11有特殊的含义,其他的没有任何含义;

    15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
    OF DF IF TF SF ZF AF PF CF

    标志位的符号
    零标志ZF(Zero flag) ZR(1) NZ(0)
    奇偶标志PF(Parity flag) PE(1) PO(0)
    符号标志SF(Sign flag) NG(1) PL(0)
    进位标志CF(Carry flag) CY(1) NC(0)
    溢出标志OF(Over flow flag) OV(1) NV(0)
    方向标志DF(Direction flag) DN(1) UP(0)
    中断标志IF(Interrupt flag) EI(1) DI(0)
    辅助标志AF(Auxiliary carry flag) AC(1) NA(0)

    零标志ZF

    flag的第6位

    它记录相关指令执行后,

    • 结果为0,ZF=1;
    • 结果非零,ZF=0;

    例如:

    mov ax,1
    sub ax,1
    
    mov ax,1
    and ax,0
    

    指令执行后,结果为0,则ZF=1;

    mov ax,2
    sub ax,1
    
    mov ax,1
    or ax,1
    

    指令执行后,结果为1,则ZF=0;

    在8086CPU的指令集中,有的指令的执行事影响标志寄存器的,例如:add,sub,mul,div,inc,or,and等。有的不影响,如:mov push,pop等传送指令;

    奇偶标志PF

    flag的第二位

    它记录指令执行后,结果的所有二进制位中1的个数:

    • 为偶数,PF=1;
    • 为奇数,PF=0;

    例如:

    mov al,1
    add al,10
    

    执行后,PF=0;

    mov al,1
    or al,10
    

    执行后,PF=1;

    符号标志SF

    flag的第七位

    它记录指令执行后:

    • 结果为负,SF=1;
    • 结果为正,SF=0;
    mov al,10000001b
    add al,1
    

    执行后SF=1;

    进位标志CF

    flag的第0位

    在进行 无符号数运算 的时候,它记录的运算结果的最高有效位项更高位的进位值,或从更高位的借位值;

    例:

    mov al,98h
    add al,al   ;(al)=30h,cf=1
    add al,al   ;(al)=30h,cf=1
    

    溢出标志OF

    flag的第11位

    在进行 有符号数运算 的时候,如果结果超出了及其所能表示的范围称为溢出;

    溢出时OF=1;

    注意:

    • CF是对 无符号 数运算有意义的标志位;
    • OF是对 有符号 数运算有意义的标志位;

    例如:

    mov al,0F0H
    add al,78H
    

    CF=1,OF=0;
    对于无符号运算,0F0H+78H有进位,CF=1;对于有符号数运算,不发生溢出,OF=0;

    例如:

    sub al,al
    ;0h=0000 0000b
    ;CF=0    OF=0    SF=0    ZF=1    PF=1
    
    mov al,10h
    ;10h=0001 0000b
    ;CF=0    OF=0    SF=0    ZF=1    PF=1
    
    add al,90h
    ;90h=1001 0000b
    ;ans=1010 0000b
    ;CF=0   OF=0    SF=1    ZF=0    PF=1
    
    mov al,80h
    ;80h=1000 0000b
    ;CF=0   OF=0    SF=1    ZF=0    PF=1
    
    add al,80h
    ;80h=1000 0000b=128d
    ;ans=1 0000 0000b=256d
    ;CF=1   OF=1    SF=0    ZF=1    PF=1
    
    mov al,0FCH
    ;0FCH=1111 1100b=252d
    ;CF=1   OF=1    SF=0    ZF=1    PF=1
    
    add al,05h
    ;05h=0000 0101b
    ;ans=1 0000 0001b=257d
    ;CF=1   OF=0    SF=0    ZF=0    PF=0
    
    mov al,7DH
    ;7DH=0111 1101b=125d
    ;CF=1   OF=0    SF=0    ZF=0    PF=0
    
    add al,0BH
    ;0BH=0000 1011b=11d
    ;ans=1000 1000b=136d
    ;CF=0   OF=1    SF=1    ZF=0    PF=1
    
    

    总结:

    • CF只看八位二进制计算后的第九位的值
    • OF看计算后的值是否在-128~127内
    • SF只看有符号数的第8位
    • ZF看8位是否都为0
    • PF看8位里的1的个数
    • 标志寄存器的改变仅在非传送指令执行时

    adc指令

    adc是带进位加法指令,他利用了CF位上记录的进位值;

    格式:
    adc 操作对象1,操作对象2

    功能:
    操作对象1=操作对象2+CF

    例如:adc ax,bx==(ax)=(ax)+(bx)+CF

    mov ax,2
    mov bx,1
    sub bx,ax
    adc ax,1
    
    (ax)=(ax)+1+CF=4
    
    mov al,98h
    add al,al
    adc al,3
    
    (ax)=(ax)+3+CF=30H+3+1=34H
    
    • adc指令和add指令相配合可以对更大的数据进行加法运算;
    • adc指令加上CF值的含义由adc之前的指令决定,如果CF是由sub设置,它的含义就是借位值,由add设置就是金为珩值;

    编写一个对两个128位进制数据进行相加的子程序:

    add128:
    push ax
    push cx
    push si
    push di
    sub ax,ax   ;置CF为零
    mov cx,8
    
    s:
    mov ax,[si]
    adc ax,[si]
    mov [si],ax
    
    inc si
    inc si
    inc di
    inc di
    ;注意这里只能这么写,不能改成add si,2,否则会置CF为零
    
    loop s
    pop di
    pop si
    pop cx
    pop ax
    

    sbb指令

    sbb是带借位减法指令,利用了CF位上记录的借位值

    格式:
    sbb 操作对象1,操作对象2

    功能:
    操作对象1=操作对象1-操作对象2-CF

    比如:
    sbb ax,bx实现:(ax)=(ax)-(bx)-CF

    sbb指令执行后,将对CF进行设置;

    cmp指令

    cmp是比较指令,功能相当于减法指令,但 不保存结果

    cmp指令执行后,将对标志寄存器产生影响;

    格式:
    cmp 操作对象1,操作对象2

    功能:计算操作对象1-操作对象2

    不保存结果,仅仅根据计算结果对标志寄存器进行设置;

    例如:

    cmp ax,ax
    
    ZF=1
    PF=1
    SF=0
    CF=0
    OF=0
    

    cmp ax,bx 指令执行后,可以根据相关的标志位的值看出比较的结果:

    如果(ax)=(bx) (ax)-(bx)=0 ZF=1
    如果(ax) ( eq) (bx) (ax)-(bx) ( eq) 0 ZF=0
    如果(ax) (lt) (bx) (ax)-(bx)将产生借位 CF=1
    如果(ax) (ge) (bx) (ax)-(bx)不必借位 CF=0
    如果(ax) (gt) (bx) (ax)-(bx)既不必借位,结果又不为零 CF=0并且ZF=0
    如果(ax) (le) (bx) (ax)-(bx)既可能借位,结果可能为零 CF=1或ZF=1

    cmp与add、sub一样既可以对无符号数比较也可以对有符号数比较;

    不能单纯的看SF的值来判断两个操作对象的大小,因为溢出的问题;

    cmp ah,bh

    • 如果SF=1,OF=0:OF=0说明没有溢出,逻辑上真正的结果的正负和实际结果的相同;SF=1,实际结果为负,所以逻辑上为负,(ah) (lt) (bh);
    • 如果SF=1,OF=1:因为溢出导致实际结果为负,那么逻辑上真正结果为正,说明 (ah) (gt) (bh);
    • 如果SF=0,OF=1:因为溢出导致实际结果为正,那么逻辑上真正的结果必然为负,说明 (ah) (lt) (bh);
    • 如果SF=0,OF=0: (ah) (ge) (bh);

    条件转移指令

    所有条件转移指令的转移位移是[-128,127];

    通常和cmp相配合;

    cmp指令的比较结果进行转移的指令分为:

    • 根据 无符号整数 的比较结果进行转移的条件转移指令,检测ZF、CF的值;
    • 根据 有符号整数 的比较结果进行转移的条件转移指令,检测SF、OF、和ZF的值;

    根据无符号数的比较结果进行转移的条件转移指令:

    指令 含义 检测的相关标志位
    je 等于则转移 ZF=1
    jne 不等于则转移 ZF=0
    jb 低于则转移 CF=1
    jnb 不低于则转移 CF=0
    ja 高于则转移 CF=0,ZF=0
    jan 不高于则转移 CF=1或ZF=1

    DF标志和串传送指令

    flag的第10位

    功能:在串处理指令中,控制每次操作后si,di的增减;

    • DF=0:每次操作后si,di递增;
    • DF=1:每次操作后si,di递减;

    格式1:movsb

    功能:以字节为单位传送;

    • ((es)16+(di))=((ds)16+(si))
    • if(df==0): (si)=(si)=1,(di)=(di)+1;
    • if(df=0): (si)=(si)-1,(di)=(di)-1;

    格式2: movsw

    功能:以字为单位传送

    rep mobsb or rep movsw

    一般,movsbmovswrep 配合使用,rep的作用是根据cx的值,重复执行后面的串传送指令;

    对DF位的设置:

    • cld指令:将标志寄存器的DF位置0
    • std指令:将标志寄存器的DF位置1

    例如:

    data segment 
        db 'Welcome to masn!'
        db 16 dup(0)
    data ends
    ;将data段中的第一个串送到后面的空间
    
    ;传送的设置:
    ;传送的原始位置:ds:si
    ;传送的目的地址:es:di
    ;传送的长度:cx
    ;传送的方向:DF
    
    mov ax,data
    mov ds,ax
    mov si,0
    mov es,ax
    mov di,16
    mov cx,16
    cld
    rep movsb
    

    pushf和popf

    • pushf: 将标志寄存器的值压栈
    • popf: 从栈中弹出数据,送入到标志寄存器中

    https://www.cnblogs.com/31415926535x/p/10200283.html

    (end)

  • 相关阅读:
    浅谈独立使用NDK编译库文件(Android)
    Ubuntu 13.04 安装使用clang
    一道TOPK问题
    exp-00091 oracle错误的解决办法
    win32多线程程序设计笔记(第四章下)
    数据库索引的实现原理 (转)
    [置顶] linux常用命令手册
    ZigBee研究之旅(二)
    java中length,length(),size()区别
    浅谈href=#与href=javascript:void(0)的区别
  • 原文地址:https://www.cnblogs.com/31415926535x/p/10200283.html
Copyright © 2011-2022 走看看