flag 寄存器
CF:进位标志位,产生进位CF=1,否则为0
PF:奇偶位,如010101b,则该数的1有3个,则PF=0,如果该数的1的个数为偶数,则PF=1。0也是偶数
ZF:在相关指令执行后(运算和逻辑指令,传送指令不影响ZF的值),其结果为0,则ZF=1,否则为0。
SF:符号标志位,如果结果为负,则SF=1,否则为0,SF是对有符号运算的一种结果记录
DF:方向标志位,控制每次操作之后si、di的增减。df=0,递增,否则递减。串传送指令movsb就是根据df的值,实现si和di的递增或者递减,movsw是传递一个字型数据。movsb和movsw通常与rep搭配使用,rep movsb就相当于
s: movsb
loop s
rep的指令是根据cx的值重复执行串传送指令。
cld和std分别可以将df位置0和置1。
下面利用rep movsb指令将data段的第一个字符串移动到它后面的空间
assume cs:code, ds:data
data segment
db 'Welcome to nasm!'
db 16 dup (0)
data ends
code segment
start:
mov ax, data
mov ds, ax
mov si, 0 ;定义了原始地址的段地址和偏移地址
mov ex, ax
mov di, 16 ;定义了目标地址的段地址和偏移地址
mov cx, 16 ;循环16次
cld ;使df=0,si和di递增
rep movsb ;默认就是将原始地址ds:si传递到目标地址es:di
code ends
end start
OF:溢出标志位,发生溢出,OF=1,否则为0。CF是针对无符号的,OF是针对有符号的。
adc和sbb指令
在相加的两个数字,都大于16位,则需要用adc来计算。
可以看到0198h和0183h相加时,低位需要进位,这时低位的加法就可以用adc指令
mov ax, 0198h
mov bx, 0183h
adc al, bl
add ah, bh
这样ax中存放的就是031B了。adc是用来处理有进位的加法的指令。
sbb是带借位的减法指令,和adc一样,是利用CF位记录的借位值或进位值。
cmp指令
cmp指令相当于减法指令,但不保存结果,只会影响标志寄存器的值,如
cmp ax, ax
则结果位0, pf=1, zf=1, sf=0, cf=0, of=0
cmp指令执行后,可以通过sf和of两个标志位判断其大小,之所以不能单纯用sf判断,是因为有可能发生溢出现象。
检测比较结果的条件转移指令
jcxz就是一个条件转移指令,不过它是检测cx中的值是否为0,为0,就jmp,下面的指令是检测标志寄存器的相关位的值,如果该值满足,则jmp。通常和cmp指令一同使用。这样的效果就和c语言的if语句类似。
指令 | 含义 | 检测的相关标志位 |
---|---|---|
je | 等于则转移 | zf=1 |
jne | 不等于则转移 | zf=0 |
jb | 低于则转移 | cf=1 |
jnb | 不低于则转移 | cf=0 |
ja | 高于则转移 | cf=0且zf=0 |
jna | 不高于则转移 | cf=1或zf=1 |
e:equal
ne: not equal
b: below
nb: not below
a: above
na: not above
pushf和popf指令
pushf是将标志寄存器的值压栈,popf是从栈中弹出数据,送入标志寄存器中。