• 汇编入门学习笔记 (十)—— 标志寄存器、串传送指令


    疯狂的暑假学习之  汇编入门学习笔记 (十)——  标志寄存器


    參考: 《汇编语言》 王爽 第11章


    CPU内部有一种特殊的寄存器叫标志寄存器(flag)。它与ax,bx。cx等其它寄存器不同,它不是用来存放数据的,而是用来存放状态的。

    flag寄存器是按位器作用的,即仅仅有0和1。


    flag寄存器的结构:

    15     14    13    12     11     10     9     8     7     6     5     4     3     2     1     0

                                      OF     DF    IF   SF   ZF                 AF         PF         CF


    在debug中标志位的表示:

    标志              1               0

    of                 OV             NV

    sf                 NG             PL

    zf                 ZR              NZ

    pf                 PE             PO

    cf                 CY             NC

    df                 DN             UP



    1. ZF标志


    零标志位。假设上条相关指令结果为0,那门ZF=1,不为0那门ZF=0

    样例:

    mov ax,1
    sub ax,1


    mov ax,1
    and ax,0

    运行后zf为1


    add,sub,mul,div。inc,or,and等这些运算指令会影响标志寄存器

    mov,push,pop等转移指令对标志寄存器没有影响


    2. PF 标志


    奇偶标志位。是0是1的规则 ,类似于奇校验。

    假设上条相关指令结果二进制中1的个数为偶数,则PF=1,为奇数则PF=0 。


    样例:

    mov al,1
    add al,10

    al = 00001011b

    pf = 0


    mov al,1
    or al,2


    al = 00000011b

    pf = 1


    3. SF标志


    符号标志位。

    假设上条相关指令结果为负数,则SF=1,正数则SF=0

    本质就是看第一位是否为1


    mov al,10000001b
    add al,1


    SF = 1


    4. CF标志


    表示无符号计算中的进位(注意:inc和dec指令是不影响CF的。但会影响ZF与OF)


    样例:

    mov al,98H
    add al,al

    CF = 1


    相减为负数,也会使得CF = 1


    mov ax,1
    sub ax,2


    5. OF标志


    表示有符号计算的溢出(注意:inc和dec指令是会影响OF的)


    比如8位补码 表示的数的范围  -128~127


    样例:

    mov al,0F0H
    add al,88H


    -16+(-120) = -136


    超过了范围,所以OF = 1



    6. abc 指令


    带进位的加法指令

    abc ax,bx

    相当于(ax)=(ax)+(bx)+CF



    样例:实现两个128位数据相加


    assume cs:code,ds:data
    
    data segment
    	db 88h,88h,88h,88h,88h,88h,88h,88h,88h,88h,88h,88h,88h,88h,88h,88h
    	db 11h,11h,11h,11h,11h,11h,11h,11h,11h,11h,11h,11h,11h,11h,11h,11h
    data ends
    
    code segment
    
    start:	mov ax,data
    	mov ds,ax
    		
    	mov si,0
    	mov di,16
    		
    	mov cx,8
    		
    	call add128
    		
    add128:	push ax
    	push cx
    	push si
    	push di
    		
    	sub ax,ax    ;将CF设置为0
    s:	mov ax,[si]
    	adc ax,[di]
    	mov [si],ax
    	inc si      ;不用add是由于add会改变CF的值
    	inc si
    	inc di
    	inc di
    	loop s
    		
    	pop di
    	pop si
    	pop cx
    	pop ax
    		
    		
    
    code ends
    
    end start
    


    7. sbb指令


    sbb是带借位的减法指令

    sbb ax,bx 相当于(ax)=(ax)-(bx)-CF


    8. cmp指令


    cmp是比較指令。相当于减法,但不保存结果仅仅改变flag


    cmp ax。bx

    对于无符号数来说

    假设(ax)=(bx)     则(ax)-(bx)=0。   所以:zf = 1;

    假设(ax)!=(bx)  则(ax)-(bx)!

    =0,所以:zf = 0。

    假设(ax)< (bx)    则(ax)-(bx)会产生错位。所以:cf = 1;

    假设(ax)>(bx)   则(ax)-(bx)不会产生错位,结果也不可能为0, 所以:cf = 0 而且zf = 0。

    能够这么说:

    zf = 1  说明 (ax)=(bx)

    zf = 0  说明 (ax)!=(bx)

    cf = 1  说明(ax)< (bx)

    cf = 0 说明   (ax)>= (bx)

    cf = 0 而且zf = 0  , 说明(ax)>(bx)

    cf = 1 或者zf=1,     说明 (ax)<=(bx)


    对于有符号数来说

    zf = 1  说明 (ax)=(bx)

    zf = 0  说明 (ax)!=(bx)

    sf=1 而且 of=0,说明(ax)<(bx)

    sf=0 而且 of=1,说明(ax)<(bx)

    sf=1 而且 of=1,说明(ax)>(bx)

    sf=0 而且 of=0。说明(ax)>=(bx)



    9. 检測比較结果的条件转移指令



    对于无符号数:


    je          等于则转移         zf=1

    jne        不等于则转移      zf=0

    jb          低于则转移         cf=1

    jnb        不低于则转移      cf=0

    ja          高于则转移         cf=0且cf = 0

    jna        不高于则转移      cf=1或zf=1


    各个字母的意思:

    j:jmp

    e:equal

    ne:not equal

    b:below

    nb:not below

    a:above

    na:not above


    比如实现:假设(ah)=(bh)则(ah)=(ah)+(ah),否则(ah)=(ah)+(bh)

        cmp ah,bh
        je s
        add ah,bh
    s: add ah,ah


    样例:计算data段中为8的数的个数,记录在ax中

    assume cs:code,ds:data
    
    data segment
    	db 8,11,23,8,2,3,8,8
    data ends
    
    code segment
    
    start:	mov ax,data
    	mov ds,ax
    		
    	mov si,0
    	mov ax,0
    	mov cx,8
    s:	cmp byte ptr ds:[si],8
    	jne next
    	inc ax
    next:	inc si
    	loop s
    		
    	mov ax,4c00H
    	int 21H
    		
    	
    code ends
    
    end start


    10. DF 标志位和串传送指令



    df=0  每次操作后si、di递增;

    df=1 每次操作后si、di递减;


    movsb

    功能:将ds:si 指向的内存单元中的字节送入es:di中。然后依据标志寄存器df位的值。将si和di递增或递减1

    相当于:

    (1)((es)*16+(di))=((ds)*16+(si)

    (2)df=0则:(si)=(si)+1

                           (di)=(di)+1

             df=1则:(si)=(si)-1

                           (di)=(di)-1


    movsw

    功能:于movsb同样,仅仅是是传送一个字,然后就是si和di是递增或递减2




    指令cld。std

    cld:将df设置为0

    std:将df设置为1


    rep指令

    功能:依据cx的值反复运行。后面的串指令。

    格式:rep movsb



    样例:复制data中的'Welcome to masm!'

    assume cs:code,ds:data
    
    data segment
    	db 'Welcome to masm!'
    	db 16 dup(0)
    data ends
    
    code segment
    
    start:	mov ax,data
    	mov ds,ax
    		
    	mov es,ax
    	mov di,16
    	mov si,0
    	mov cx,16
    	cld
    	rep movsb
    		
    	mov ax,4c00h
    	int 21h
    		
    code ends
    
    end start


    11. pushf和popf


    pushf的功能是将标志寄存器的值压栈。而popf是从栈中弹出数据。送入标志寄存器中



  • 相关阅读:
    eclispe安装tomcate没有srver解决
    反射常见方法
    让用户输入一个日期字符串,将其转换成日期格式, 格式是(yyyy/MM/dd,yyyyMMdd,yyyy-MM-dd)中的一种, 任何一种转换成功都可以; 如果所有的都无法转换,输出日期格式非法。
    List 接口中ArrayList Vector LinkedList 比较
    抽象类
    js核心知识
    JQgrid学习网站
    小练习---递归求5!
    map()
    小练习---阶乘
  • 原文地址:https://www.cnblogs.com/mthoutai/p/7118200.html
Copyright © 2020-2023  润新知