以下练习来自CSAPP 3.21:
int loop_while(int a, int b)
{
int result = 1;
while (a < b)
{
result *= (a+b);
a++;
}
return result;
}
gcc生成以下汇编代码:
;a at %ebp+8, b at %ebp+12
movl 8(%ebp), %ecx
movl 12(%ebp), %ebx
movl $1, %eax ; this one
cmpl %ebx, %ecx
jge .L11
leal (%ebx,%ecx), %edx
movl $1, %eax ; and this one
.L12:
imull %edx, %eax
addl $1, %ecx
addl $1, %edx
cmpl %ecx, %ebx
jg .L12
.L11: ......
我对第3行和第7行的
movl $1, %eax
感到困惑:%eax
在第4、5、6行中没有被修改cmpl %ebx, %ecx
jge .L11
leal (%ebx,%ecx), %edx
无需再次执行
movl
。我尝试使用
x86_64-apple-darwin15.3.0
在gcc 4.2.1
上生成汇编代码 movl $1, %eax
cmpl %esi, %edi
jge LBB0_2
.align 4, 0x90
LBB0_1:
leal (%rsi,%rdi), %ecx
imull %ecx, %eax
incl %edi
cmpl %edi, %esi
jne LBB0_1
LBB0_2:
popq %rbp
retq
.cfi_endproc
找不到与重复的
movl
等效的指令。编写第二个
movl $1, %eax
有什么意义? 最佳答案
从OS X 10.8开始,Apple一直将gcc
链接到clang
,因此第一个代码实际上是由clang
生成的。
即使使用-O2
和-O3
,我的Clang 3.7.1也generates相同的代码。正如您正确注意到的那样,第二个movl
是毫无意义的。
如果可以使用inform中当前的版本进行复制,则可能需要trunk LLVM / Clang团队。