This question already has an answer here:
Why does clang produce inefficient asm with -O0 (for this simple floating point sum)?
                                
                                    (1个答案)
                                
                        
                                7天前关闭。
            
                    
我开始学习汇编语言,因此我使用命令gcc -S file.c获取我的C代码的汇编版本。

一切正常,但是我注意到当我输入简单的代码时,例如:

void    ft_return_strlen(char *str)
{
    int     a;

    a = strlen(str);
    return (a);
}


gcc -S file.c命令给了我这个:

_ft_return_strlen:
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register %rbp
    subq    $16, %rsp
    movq    %rdi, -8(%rbp)
    movq    -8(%rbp), %rdi
    callq   _ft_strlen
    movl    %eax, -12(%rbp)
    movl    -12(%rbp), %eax
    addq    $16, %rsp
    popq    %rbp
    retq


即使此功能没用,为什么gcc给我这些行?

    movq    %rdi, -8(%rbp)
    movq    -8(%rbp), %rdi


他们不是没用吗?如果这些行真的没用,它们是来自我的代码还是来自gcc?有办法改善吗?

最佳答案

未经优化,编译器会为变量str(-8(%rbp))分配空间。最上面的所有代码都是在寄存器rbp和rsp之间为本地变量在堆栈上留出空间。

函数调用将其放在寄存器rdi中,但是调试器需要在名为str的变量中看到它。并且,如果要在调试器中更改变量str,则需要将新值作为strlen的参数复制回去。

然后,变量a -12(%rbp)也会发生同样的情况,必须将其从返回寄存器rax复制,然后再复制回以返回,以防万一您在调试器中对其进行了编辑。

通过优化,变量将被完全丢弃,但调试器会意识到等效变量位于寄存器中。最大限度地优化,可以删除整个功能,或将其替换为jmp以使其醒目,但是您根本无法对其进行调试!

07-24 09:44
查看更多