我是集会新手,并已开始通过作业学习它。但是,我不太确定使用"测试"命令:
第一个命令是" anding"常数1和eax一起。如果eax像10101010,1是:00000001,那么" anding"它们在一起会产生:0。但测试寄存器的最低四位与什么有什么关系 - 为什么它很重要?整个表达式在做什么?
8049ac0: 83 e0 01 and $0x1,%eax // "and" these bits together
8049ac3: 84 c0 test %al,%al // check the last
8049ac5: 74 05 je 8049acc <level_4+0x60> // if it is equal, then skip down.
答案 0 :(得分:1)
test
指令实际上是多余的,所以没有做任何有用的事情。它可能是因为生成此代码的编译器在优化方面不是很擅长,因此包含了一条不会对任何事情造成伤害的不必要的指令。
and $1,%eax ; clear all bits of %eax except the lowest, set ZF if all bits are now zero
test %al,%al ; set ZF if %al (the lowest 8 bits of %eax) are all clear
je somewhere ; branch if ZF is set
因此and
指令将ZF标志设置为等于%eax最低位的补码,而test
指令将再次设置为相同的东西。这可能来自以下代码:
if (var&1) {
... do something ...
}
在代码片段之前将var
加载到%eax
,而分支目标就在}
之后。首先生成的代码将var & 1
计算到临时寄存器(and
指令),然后测试结果是否为非零(test
指令),然后分支结束如果测试为假(...do something...
指令),则为je
。
答案 1 :(得分:0)
and $0x1,%eax
使EAX
的一个位保持不变:最右边或最不重要的一个。如果设置了这个位,则EAX
是奇数,而在另一种情况下它是偶数。 test %al,%al
(EAX
的最低有效8位)实际上相应地将该标志设置为该位。 Z = 1(jz / je跳跃)意味着EAX
是偶数。
答案 2 :(得分:0)
该寄存器被命名,例如:
32位 - &gt; EAX
--AH-- --AL-- 8bits each.
-----AX------ 16bits
---------EAX------------ 32bits
在x86 Wikipedia中更详细地解释了CPU寄存器和图片,以便更好地理解
在你的情况下,除了最低位和测试EAX(AL)的8个最低位之外,你要清除所有EAX位(32位寄存器)。 test
instruction将执行Bitwise AND
并相应地更新cpu标志,je
将使用此标志(如果相等则跳转,该测试为零标志)。在这种情况下,检查EAX的最低8位是否为0,如果是,则跳转到跳转中指示的地址。