【发布时间】:2020-07-07 10:07:43
【问题描述】:
当我在https://godbolt.org 上使用不同的编译器时,我注意到编译器生成这样的代码是很常见的:
push rax
push rbx
push rcx
call rdx
pop rcx
pop rbx
pop rax
我知道每个push 或pop 做两件事:
- 将操作数移入/移出堆栈空间
- 递增/递减堆栈指针 (rsp)
所以在我们上面的例子中,我假设 CPU 实际上正在执行 12 次操作(6 次移动,6 次加/减),不包括 call。组合添加/订阅不是更有效吗?例如:
sub rsp, 24
mov [rsp-24], rax
mov [rsp-16], rbx
mov [rsp-8], rcx
call rdx
mov rcx, [rsp-8]
mov rbx, [rsp-16]
mov rax, [rsp-24]
add rsp, 24
现在只有 8 个操作(6 个移动,2 个加/减),不包括 call。为什么编译器不使用这种方法?
【问题讨论】:
-
每条指令的大小是多少?推送/弹出多少字节,寄存器偏移寻址多少字节?以 xor rax,rax 与 mov rax,0 为例。
标签: assembly x86 x86-64 cpu-architecture micro-optimization