Gcc 测试指令和指令x86
我正在将C代码转换为x86程序集,我有一行代码:Gcc 测试指令和指令x86,gcc,assembly,x86,Gcc,Assembly,X86,我正在将C代码转换为x86程序集,我有一行代码: if (bitmask & bit) 我使用gcc生成汇编代码,这部分代码是: andl %edx, %eax testl %eax, %eax je else (EAX为位,EDX为位掩码) andl指令是必需的还是可以与修改后的testl一起使用,如下所示: testl %edx, %eax je else ?您只需要testl或andl,但不能同时使用两者 让我们看看GCC生成的代码 代码 andl %edx, %eax 将
if (bitmask & bit)
我使用gcc生成汇编代码,这部分代码是:
andl %edx, %eax
testl %eax, %eax
je else
(EAX为位,EDX为位掩码)
andl
指令是必需的还是可以与修改后的testl
一起使用,如下所示:
testl %edx, %eax
je else
?您只需要
testl
或andl
,但不能同时使用两者
让我们看看GCC生成的代码
代码
andl %edx, %eax
将and操作的结果放入%eax
对目标(第一个)和源(第二个)操作数执行位“与”运算,并将结果存储在
目标操作数位置。源操作数可以是立即数、寄存器或内存位置;这个
目标操作数可以是寄存器或内存位置。(但是,在中不能使用两个内存操作数。)
如果第一个和第二个操作数的对应位均为1,则结果的每一位都设置为1;
否则,它将设置为0
OF和CF标志被清除;根据结果设置SF、ZF和PF标志。AF标志的状态为
未定义
(PDF第121和122页)
现在让我们看看testl
testl %eax, %eax
testl
也执行与您刚才在特定行中执行的相同的操作
特别是testl
计算第一个操作数(源1操作数)和第二个操作数(源2操作数)的逐位逻辑“与”,并根据结果设置SF、ZF和PF状态标志。然后丢弃结果
在64位模式下,使用REX.R形式的REX前缀允许访问其他寄存器(R8-R15)。使用REX.W形式的REX前缀将操作提升到64位。有关编码数据和限制,请参阅本节开头的汇总表
在这种情况下,两个操作数是相同的,和l的结果是相同的。如果操作数为0,则将其与自身相加生成0。将任何其他值与自身相加将生成一个非零值
总之
我不确定GCC为什么同时生成和testl
指令。我不认为这两种情况都是必要的,因为testl
执行and操作,并且都设置了je
指令所需的ZF。请显示一个示例。所提供的信息无法回答这个问题。您使用的优化级别是什么?@Olaf:这与优化无关。OP想知道testl
是否有必要,他的困惑似乎是andl
是否设置了ZF,或者他可能不知道je
需要适当设置ZF。@EricJ。我的猜测是,原始海报所问的真正问题是“为什么GCC生成这个显然不必要的指令?”@EricJ。如果没有必要,那么我们应该去掉[gcc]标记和C代码,并严格限制它为汇编,不是吗?@EvanCarroll:这不是我的问题,但我确实觉得上下文与问题相关,我个人不会删除它。andl
指令根据结果设置Z标志。@RaymondChen:你能举出一个来源吗?我已经好几年没组装了。。。20年?但是我刚才查找的源代码没有说明ZF设置为和。如果保存eax和edx不重要,它是否可以减少为testl%edx,%eax
;根据结果设置SF、ZF和PF标志。AF标志的状态未定义。
换句话说,test
完全等同于和
,结果被丢弃。@EricJ:我假设代码已被翻译而未经优化,因此用于提取的和if和TESTL
将测试if
条件。一个优化步骤可以将它们折叠为一个操作。但你没有回答这个问题<正如OP所假设的那样,仅代码>TESTL
就足够了。