x86 addl vs subl

时间:2012-04-12 15:41:56

标签: c assembly compiler-construction x86 clang

我只是注意到Clang编译了这个语句(当然没有任何优化):

--x; /* int x; */

成:

addl    $4294967295, %ecx       ## imm = 0xFFFFFFFF

为什么呢?使用addl代替“明显的”subl有什么好处吗?或者它只是一个实现事实?

让我觉得这个是:

x -= 1;

变为:

subl    $1, %eax

Clang info:

Apple clang version 3.0 (tags/Apple/clang-211.12) (based on LLVM 3.0svn)
Target: x86_64-apple-darwin11.2.0
Thread model: posix

1 个答案:

答案 0 :(得分:4)

此行为与clang处理预递减的方式有关,而不是像sub-and-assign这样的二元运算符。请注意,我将尝试在clang级别解释您为何看到此行为。我不知道为什么选择以这种方式实现它,但我想这只是为了便于实现。

我在此处引用的所有功能都可以在ScalarExprEmitter内的lib/CodeGen/CGExprScalar.cpp课程中找到。

函数EmitScalarPrePostIncDec以相同的方式处理前/后递减/递增:以add1作为第二个参数发出LLVM -1指令,取决于表达式分别是增量或减量。

因此,

--x

将在LLVM IR中以类似

的方式结束
add i32 %x, -1

,很自然地,转换为x86就像

add $0xffffffff, %ecx
另一方面,二元运算符的处理方式各不相同。在你的情况下,

x -= 1

将由EmitCompoundAssign处理,而EmitSub又会调用sub i32 %x, 1 。将发出类似以下LLVM IR的内容:

{{1}}