汇编入门学习笔记 (十)—— 标志寄存器、串传送指令 1. ZF标志 2. PF 标志 3. SF标志 4. CF标志 5. OF标志 6. abc 指令 7. sbb指令 8. cmp指令 9. 检測比較结果的条件转移指令 10. DF 标志位和串传送指令 11. pushf和popf
疯狂的暑假学习之 汇编入门学习笔记 (十)—— 标志寄存器
參考: 《汇编语言》 王爽 第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
零标志位。假设上条相关指令结果为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是从栈中弹出数据。送入标志寄存器中