我正在观察为下面的函数here创建的程序集.

int square(int num) {
    return num;
}

这是为上面的函数生成的程序集:

square:
        push    rbp
        mov     rbp, rsp
        mov     DWORD PTR [rbp-4], edi
        mov     eax, DWORD PTR [rbp-4]
        pop     rbp
        ret

我的问题是,我可以把它重写到这里,然后假定它运行良好吗?

square:
        push    rbp
        mov     rbp, rsp
        mov     eax, edi
        pop     rbp
        ret

有什么必要先把edi移到[rbp-4],然后再把[rbp-4]移到eax?由于源和目标都是寄存器,我认为我们可以在单个移动指令中移动数据.

编辑

我的问题是关于未优化的代码版本,我知道如果我用-O1编译它,它会发出更短、更简洁的代码.但我的问题是关于额外mov条指令的语义.

推荐答案

如果没有优化,编译器将生成遵循语言的文字规范的步骤.在C中,函数的参数本质上是局部变量,就像你在函数内部声明的一样.这段C代码:

int square(int num)
{
    …
}

在C标准的语义中,很像:

int square(?)
{
    int num = value that the caller passed as the first argument;
    …
}

在没有优化的情况下,编译器将遵循此模型.当 routine 启动时,编译器设置一个堆栈帧,并将参数(在寄存器中)存储到参数(在堆栈中).

然后,return num;从堆栈中加载参数.

启用优化后,编译器将删除不必要的堆栈使用.

C++相关问答推荐

CC crate 示例不会与C函数链接

如何在不修改字符串缓冲区早期使用的情况下覆盖字符串缓冲区

在Windows上构建无聊的SSL x64

Mbed TLS:OAEP的就地en—/decryption似乎不起作用'

球体—立方体重叠:无、部分或全部?

如何设置指针指向在函数中初始化的复合文字中的整数?

为什么GCC可以调用未定义的函数?

如何将字符串传递给函数并返回在C中更改的相同字符串?

如何在C中使printf不刷新标准输出?

为什么我不能只在内存地址中添加一个int来寻址任何数组?

如何将字符**传递给需要常量字符指针的常量数组的函数

为什么Fread()函数会读取内容,然后光标会跳到随机位置?

Cairo STM32MP1 cairo_Surface_WRITE_TO_PNG始终返回CAROLIO_STATUS_WRITE_ERROR

我在C中运行和调试时得到了不同的输出

我正在使用c学习数据 struct ,在学习堆栈时,我试图将中缀转换为后缀,并编写了这段代码.代码未给出输出

一元运算符

将数组返回到链表

如何向 execl 创建的后台程序提供输入?

clion.我无法理解 Clion 中发生的 scanf 错误

在 printf() 格式说明符中使用字段宽度变量