例如,在使用ADC、SBB等汇编命令时,我们为了内心的好奇心,必须理解FLAG寄存器(EFL )的内容。 用二进制详细查看各标志位的值。 而且,这些都需要使用标志寄存器的指令等,这一点一目了然。 - -
我等不及要写测试代码看看那个秘密:
#include iostream
输入主(语音) )。
{
__asm
{
mov al,0xff
mov dl,0x01
add al,dl
adc al,dl
}
返回0;
}
还是用内敛组件的形式说明。 现在,假设给了0xff。 为什么把AL定为0xff是为了能够进位。 我觉得这个数很方便。 当然,如果两个数的和发生进位就好了(这里是为了测试进位的CF位)。 现在可以将0x01之和正好向上舍入以测试奇偶校验和零值。
在上面的红色代码中打上断点,运行程序中断到此为止,打开VC寄存器窗口,即可看到各寄存器的值。 这里是EFL=? 标志寄存器的值。
在此查看标志寄存器的各标志位的值有两种方法。
第一,将EFL的值转换为二进制,并通过二进制位查看标志位的值。
第二,如果您的寄存器窗口中没有显示标志,则在寄存器窗口中单击鼠标右键,然后选择“标志”以显示标志位的值。 例如,情况如下:
OV=? UP=? EI=? PL=? ZR=? 交流=? PE=? CY=?
这里有对照表:
根据EFL的二进制数据进行位比对,可以知道各标志位的值。
标志值将显示在第一个断点处。
ov=0up=0ei=1pl=0zr=0ac=0pe=0cy=0
在此,EI=1表示中断状态---。
让我们看看EFL=0x00000202(100000010 )的对号入座。
1 0 0 0 0 0 0 0 1 0
IF TF SF ZF AF PFCF
只有if(ei|di )为1,并且VC寄存器窗口中仅由括号中的一个表示。
好的! 查看完每个标志位后,按F10键执行ADD AL、DL一词。
让我们看看每个标志位的值。 ov=0up=0ei=1pl=0zr=1ac=1pe=1cy=1
看看标志寄存器的值吧。 EFL=0x00000257(1001010111 )。
1 0 0 1 0 10 1 1 1
IFTF SFZF AF PF CF
这里,IF指示中断,ZF指示目标操作数的结果为0,AF指示是否已进行到(AL为1字节)加法的一半(低4比特),也可以指示是否存在借位)。 PF表示偶数,CF表示发生进位,也可以表示借位。
此外,如果按F10键执行完语句ADC AL,DL,则ADC是进位加法,结果是
为: AL = AL + DL + CF。这时AL: 0 + 0x1 + 1 = 0x02。
标志位值: OV = 0 UP = 0 EI = 1 PL = 0 ZR = 0 AC = 0 PE = 0 CY = 0 这里就不做解释了吧 - -
这里特别说下:
DF:是控制标志位为方向标志,在串处理指令中控制处理信息的方向用。当DF为1时,每次操作后使变址寄存器SI和DI减小,这样就使串处理从高地址向低地址方向处理。当DF为0时相反。。
TF:当TF被置为1时,CPU进入单步执行方式,即每执行一条指令,产生一个单步中断请求。这种方式主要用于程序的调试。
在这里我们要获得标志寄存器的值的话有以下这些指令:
LAHF 标志寄存器传送,把标志装入AH.
SAHF 标志寄存器传送,把AH内容装入标志寄存器.
PUSHF 标志入栈.
POPF 标志出栈.
PUSHD 32位标志入栈.
POPD 32位标志出栈.
在上边的AF位让我想到用ADC或者SBB来进行进位或借位的一个常用方法就是,我们可以在加/减两个4字节的数据是可以高2字节、低2字节分别相加。通过ADC/SBB可以在计算高2字节想加/减时获得CF值,用来进行进位或借位。
例如:
mov ax, low1
add ax, low2
mov sumLow, ax
mov ax, high1
adc ax, high2
mov sumHigh, ax
这样就实现了进位, low1, low2分别表示第一个数和第二个数的低2字节, high1, high2分别表示第一个数和第二个数的高2字节。 当 add ax, low2 产生了进位时, CF = 1。 后边在执行高2字节相加时用ADC会去获取CF的值。 sumHigh = high1 + high2 + CF。 最后得到的数就是高2字节之和(sumHigh)与低2字节之和(sumLow)的合并。形如:
DWORD var = 0;
WORD sumHigh = 0;
WORD sumLow = 0;
C++:
var |= sumHigh;
var <<= 16;
var |= sumLow;
ASM:
movzx eax, word ptr[ sumHigh ]
shl eax, 10h
or eax, dword ptr[ sumLow ]
mov var, eax
这便实现了进位。 借位的道理是一样的, 这里就不阐述了。。 - -
终于写完了~~累死了。。 有什么错误希望大家帮我纠正 - -