以下练习来自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.0gcc 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团队。

10-07 19:32
查看更多