标志寄存器相关
1.关于标志寄存器
标志寄存器(EFLAGS)又称为程序状态和控制寄存器(Program Status andControl Register),主要用于记录当前的程序状态。
1)进位标志(CF ->carry flag):如果运算结果的最高位产生了进位或借位操作时标志位置 1
例:定义数值宽度为 32 位,则 0xFFFFffff+2 在运算过程中出现进位。
2)奇偶标志(PF ->parity flag):运算结果值中 1 的个数为偶数置 1
例:运算结果 0x4567 中 1 的个数是?
站在计算机的角度,它是 0100010101100111B。所以有8 个 1, PF=1。
3)辅助进位标志(AF ->auxiliary carry flag):在以下情况下该标志位置1
-
字操作时,发生低字节向高字节进位或借位;
-
字节操作时,发生低4位向高4位进位或借位;
4)零标志(ZF ->zero flag):运算结果为零置 1
5)符号标志(SF ->sign flag):其结果与最高位相同;
因为有符号数的负数最高位是1,正数最高位是0;
6)单步标志(TF):单步使能置 1,当该位置 1 时,可以对程序进行单步调试。
7)中断使能标志(IF):响应可屏蔽中断置 1
8)方向标志(DF ->direction flag):字符串指令(MOVS, CMPS, SCAS, LODS 和 STOS)处理字符串,从高地址到低地址置 1(STD 和 CLD 指令设置和清除该标志位)。
9)溢出标志(OF):运算结果溢出置 1;
有符号运算的结果超过当前运算位数所能表示的范围时称为溢出;
溢出主要是给有符号运算使用的,在有符号的运算中,有如下的规律:
正 + 正 = 正 如果结果是负数,则说明有溢出
负 + 负 = 负 如果结果是正数,则说明有溢出
正 + 负 永远都不会有溢出.
2.与标志寄存器相关的一些指令
1)ADC ->进位加法指令
格式:adc r/m,r/m/imm
r表示寄存器,m表示内存地址,imm表示立即数
逗号两边不能同时为内存地址m,且两边的数据宽度要一致;
作用是逗号两边的数相加并且加上进位标志cf中的值;
例如:
adc al,cl
adc byte ptr ds:[12ff4c],2
adc byte ptr ds:[12ff4c],al
2)SBB ->带借位减法
格式:sbb r/m,r/m
两边不能同时为内存,且宽度一样;
例如:
sbb al,cl
sbb byte ptr ds:[12ff4c],2
sbb byte ptr ds:[12ff4c],al
3)XCHG ->交换数据指令
格式:xchg r/m,r/m
两边不能同时为内存,且宽度一样;
作用是交换逗号两边的数据;
例如:
xchg al,cl
4)MOVS ->移动数据,内存-内存
一般指令不能在两边都是内存的情况下传递数据;
如果想做到这一点可以用movs指令;
作用是将后面内存中的数据复制到前面的内存中;
格式:
movs byte ptr es:[edi],byte ptr ds:[esi] ->简写为:movsb
movs word ptr es:[edi],word ptr ds:[esi] ->movsw
movs dword ptr es:[edi],dword ptr ds:[esi] ->movsd
注意:
执行完后根据方向标志位df的值,和数据宽度来修改esi和edi;
例如移动word型数据时,如果df为1,则是反向复制;
也就是复制完一个字后esi和edi的值减去一个字的宽度减去两个字节;
此时esi和edi指向了下一个字;这样方便继续复制下一个字;
该指令经常用来复制字符串;
5)STOS ->将AL/AX/EAX的值储存到[EDI]指定的内存单元
格式:
stos byte ptr es:[edi] ->简写:stosb ->将al的值储存到es:[edi];内存单元宽度和寄存器的宽度要一致;
stos word ptr es:[edi] ->stosw
stos dword ptr es:[edi] ->stosd
例如:
mov eax,12345678
mov edi,12ffc4
stos dword ptr es:[edi]
注意:
执行完stos后,edi的值会受到数据宽度和方向标志位的影响;
比如:如果移动的是双字型数据,且df=0表示正向,执行完stos指令后edi的值加4个字节;
6)REP ->以计数寄存器ECX的值为次数重复执行复制指令
例如:
mov ecx,10
rep movsd
rep stosd