正如你可能已经猜到的问题是gcc
自动保存被调用保存寄存器还是应该自己做?我认为gcc
会为我做的,但是当我gcc a.c && objdump -d a.out
后写了这个代码确实gcc保存被调用者保存寄存器
void foo(void) {
__asm__ volatile ("mov $123, %rbx");
}
void main(void) {
foo();
}
我看到这个
00000000004004f6 <foo>:
4004f6: 55 push %rbp
4004f7: 48 89 e5 mov %rsp,%rbp
4004fa: 48 c7 c3 7b 00 00 00 mov $0x7b,%rbx
400501: 90 nop
400502: 5d pop %rbp
400503: c3 retq
0000000000400504 <main>:
400504: 55 push %rbp
400505: 48 89 e5 mov %rsp,%rbp
400508: e8 e9 ff ff ff callq 4004f6 <foo>
40050d: 90 nop
40050e: 5d pop %rbp
40050f: c3 retq
据ABI x86-64的是%rbx
被叫保存登记,但在这代码gcc
在修改之前未将其保存在foo
中。仅仅是因为我在调用foo()
之后没有在主要功能中使用%rbx
,或者因为gcc
不提供这样的服务,我必须在修改之前自己将其保存在foo
之前?
GCC不关注你的内联asm,它只是逐字地发布它。这取决于你做正确的事情。 –
这将是非常糟糕的代码,通过死记硬背保存和恢复每个寄存器。 –
@WeatherVane所以这意味着'gcc'不会预先保存这个寄存器,我应该自己保存它们吗? – PepeHands