从大会领域开始,很难找到一个体面的排序教程。 想找一本“傻瓜大会”一书。
我遇到过以下情况,并且'test'命令始终使用相同的地址或注册表运行。
0x08048e14 <+21>: test %esi,%esi
0x08048e16 <+23>: jne 0x8048e4b <main+76>
由于相同的注册表或地址是AND,何时不返回,这些是相同的?
答案 0 :(得分:6)
test reg, reg
(两个操作数的reg
相同)是你几乎总能看到的而不是:
cmp reg, 0
优化代码。两条指令都以相同的方式设置标志,但前者需要较少的字节进行编码,因此速度稍快。
因此,您的代码只是测试esi
寄存器是否为零。如果它不为零,则需要分支;如果它为零,执行就会没有分支。
为什么这样做?好吧,正如您似乎已经知道的那样,TEST
指令只是对其操作数进行按位-AND。那么真值表对于按位-AND说什么呢?
|===============================|
| Bit 1 | Bit 2 || AND |
|---------|---------||----------|
| 0 | 0 || 0 |
| 1 | 0 || 0 |
| 0 | 1 || 0 |
| 1 | 1 || 1 |
|===============================|
中间两种情况可以忽略,因为在这种特殊情况下,我们知道两个操作数是相同的值。因此,当esi
为0时,TEST
会将零标志(ZF)设置为1,因为按位AND的结果为0.而相反,当esi
为非时-zero,TEST
将关闭零标志,因为如果按位与AND的结果为非零。