疯狂的暑假学习之 汇编入门学习笔记 (十)—— 标志寄存器
參考: 《汇编语言》 王爽 第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是从栈中弹出数据。送入标志寄存器中