【发布时间】:2021-11-21 21:35:24
【问题描述】:
考虑以下几点:
ammarfaizi2@integral:/tmp$ vi test.c
ammarfaizi2@integral:/tmp$ cat test.c
extern void use_buffer(void *buf);
void a_func(void)
{
char buffer[4096];
use_buffer(buffer);
}
__asm__("emit_mov_rbp_to_rsp:\n\tmovq %rbp, %rsp");
ammarfaizi2@integral:/tmp$ clang -Wall -Wextra -c -O3 -fno-omit-frame-pointer test.c -o test.o
ammarfaizi2@integral:/tmp$ objdump -d test.o
test.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <emit_mov_rbp_to_rsp>:
0: 48 89 ec mov %rbp,%rsp
3: 66 2e 0f 1f 84 00 00 cs nopw 0x0(%rax,%rax,1)
a: 00 00 00
d: 0f 1f 00 nopl (%rax)
0000000000000010 <a_func>:
10: 55 push %rbp
11: 48 89 e5 mov %rsp,%rbp
14: 48 81 ec 00 10 00 00 sub $0x1000,%rsp
1b: 48 8d bd 00 f0 ff ff lea -0x1000(%rbp),%rdi
22: e8 00 00 00 00 call 27 <a_func+0x17>
27: 48 81 c4 00 10 00 00 add $0x1000,%rsp
2e: 5d pop %rbp
2f: c3 ret
ammarfaizi2@integral:/tmp$
a_func()的最后,return之前,是恢复%rsp的函数尾声。它使用add $0x1000, %rsp 产生48 81 c4 00 10 00 00。
不能只使用mov %rbp, %rsp,它只产生3个字节48 89 ec吗?
为什么 clang 不使用较短的方式 (mov %rbp, %rsp)?
通过代码大小权衡,使用add $0x1000, %rsp 代替mov %rbp, %rsp 有什么优势?
更新(额外)
即使使用-Os,它仍然会产生相同的代码。所以我认为一定有合理的理由避免mov %rbp, %rsp。
ammarfaizi2@integral:/tmp$ clang -Wall -Wextra -c -Os -fno-omit-frame-pointer test.c -o test.o
ammarfaizi2@integral:/tmp$ objdump -d test.o
test.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <emit_mov_rbp_to_rsp>:
0: 48 89 ec mov %rbp,%rsp
0000000000000003 <a_func>:
3: 55 push %rbp
4: 48 89 e5 mov %rsp,%rbp
7: 48 81 ec 00 10 00 00 sub $0x1000,%rsp
e: 48 8d bd 00 f0 ff ff lea -0x1000(%rbp),%rdi
15: e8 00 00 00 00 call 1a <a_func+0x17>
1a: 48 81 c4 00 10 00 00 add $0x1000,%rsp
21: 5d pop %rbp
22: c3 ret
ammarfaizi2@integral:/tmp$
【问题讨论】:
标签: assembly clang x86-64 micro-optimization