相关疑难解决方法(0)

什么 C/C++ 编译器可以使用 push pop 指令来创建局部变量,而不是仅仅增加一次 esp?

我相信 push/pop 指令会产生更紧凑的代码,甚至可能会运行得稍微快一点。不过,这也需要禁用堆栈帧。

为了检查这一点,我需要手动重写一个足够大的汇编程序(比较它们),或者安装和研究一些其他编译器(看看他们是否有这个选项,并比较结果) .

这是有关此问题和类似问题的论坛主题

简而言之,我想了解哪个代码更好。像这样的代码:

sub esp, c
mov [esp+8],eax
mov [esp+4],ecx
mov [esp],edx
...
add esp, c
Run Code Online (Sandbox Code Playgroud)

或这样的代码:

push eax
push ecx
push edx
...
add esp, c
Run Code Online (Sandbox Code Playgroud)

什么编译器可以生成第二种代码?他们通常会产生第一个的一些变体。

c++ x86 assembly micro-optimization compiler-optimization

1
推荐指数
1
解决办法
1905
查看次数

为什么被调用者不首先使用调用者保存的寄存器?

我们知道,根据 x86-64 约定,寄存器%rbx%rbp%r12%r15被归类为被调用者保存的寄存器。While%r10%r111是调用者保存的寄存器。但是当我在大多数情况下编译 C 代码时,例如函数P调用Q,我看到以下函数的汇编代码Q

Q:
   push %rbx
   movq %rdx, %rbx
   ...
   popq %rbx
   ret
Run Code Online (Sandbox Code Playgroud)

我们知道,由于%rbx是一个被调用者保存的寄存器,我们必须将它存储在堆栈中,并在P以后为调用者恢复它。

但它不会更简洁并通过使用调用者保存的寄存器来保存堆栈操作%r10

Q:
   movq %rdx, %r10
   ...
   ret
Run Code Online (Sandbox Code Playgroud)

所以被调用者不需要担心保存和恢复调用者的寄存器,因为调用者在调用被调用者之前已经把它推到了堆栈?

c assembly x86-64 calling-convention compiler-optimization

0
推荐指数
1
解决办法
167
查看次数