我正在将C代码转换为x86程序集,我有一行:
if (bitmask & bit)
我使用gcc生成汇编代码,这部分是:
andl %edx, %eax
testl %eax, %eax
je else
(EAX是位,EDX是位掩码)
andl
指令是必要的,还是可以使用修改后的testl
:
testl %edx, %eax
je else
答案 0 :(得分:4)
您只需要testl
或andl
,但不能同时使用。{/ p>
让我们看一下GCC生成的代码
代码
andl %edx, %eax
将和操作的结果放入%eax。
对目标(第一个)和源(第二个)操作数执行按位AND运算并将结果存储在其中 目标操作数位置。源操作数可以是立即数,寄存器或存储器位置;该 目标操作数可以是寄存器或存储器位置。 (但是,不能使用两个内存操作数 一条指令。)如果第一和第二操作数的相应位都是1,则结果的每一位都设置为1; 否则,它被设置为0.
清除OF和CF标志;根据结果设置SF,ZF和PF标志。 AF标志的状态是 未定义。
(PDF的第121页和第122页)
现在让我们看一下testl
testl %eax, %eax
testl
也会执行您在特定行中执行的相同和。
特别是testl
计算第一个操作数(源1操作数)和第二个操作数(源2操作数)的按位逻辑AND,并根据结果设置SF,ZF和PF状态标志。结果然后被丢弃。
在64位模式下,使用REX.R形式的REX前缀允许访问其他寄存器(R8-R15)。使用REX.W形式的REX前缀可将操作提升到64位。有关编码数据和限制的信息,请参阅本节开头的摘要表。
http://www.felixcloutier.com/x86/TEST.html
在这种情况下,两个操作数都相同,即andl
的结果。如果操作数为0,则将其与自身生成为0,并且自身的任何其他值都会产生非零值。
摘要
我不确定为什么GCC同时生成andl
和testl
指令。我没有看到两者都是必要的情况,因为testl
执行和操作,并且都设置了je
指令所需的ZF。