What does it mean that “registers are preserved across function calls”?

自闭症网瘾萝莉.ら 提交于 2021-02-05 09:03:38

问题


From this question, What registers are preserved through a linux x86-64 function call, it says that the following registers are saved across function calls:

r12, r13, r14, r15, rbx, rsp, rbp

So, I went ahead and did a test with the following:

.globl _start
_start:
    mov $5, %r12
    mov $5, %r13
    mov $5, %r14
    mov $5, %r15
    call get_array_size
    mov $60, %eax
    syscall

get_array_size:
    mov $0, %r12
    mov $0, %r13
    mov $0, %r14
    mov $0, %r15
    ret

And, I was thinking that after the call get_array_size that my registers would automatically (and somewhat magically) restore with the values 5. gdb shows that this is incorrect.

But I think that maybe I'm misunderstanding this. I suppose it just means that any functions that "conform to the x86-64 ABI" are supposed to restore those registers after they are finished (in other words, my get_array_size function is an invalid functino in the linux ABI), or could someone explain to me what I seem to be missing in my understanding.

Additionally, when someone says that a function should conform to the ABI, are non-globl functions supposed to do this as well? Or do the 'internal-implementations' not matter at all and only the functions I expose to the public (via globl) supposed to comply with it? Is there a notation that is typically used to say whether a function is local or global (such as in the naming scheme?).

Of course, I'm a beginner to asm so thank you very much in explaining what I may be missing.


回答1:


Correct, your hand-written asm get_array_size doesn't follow the ABI because it's clobbering call-preserved registers. That means its callers need to treat it specially, not follow the usual ABI guarantees.

The ABI doc is a standard that compiler-generated functions follow, and so should most hand-written functions unless you want to make up your own custom calling convention. See What are callee and caller saved registers? for more details about what call-preserved vs. call-clobbered means for the caller, and for the implementation of the function itself if it wants to follow the ABI.

Small private "helper" functions with custom calling conventions are fine as long as you comment them (and never try to call them from C). Especially when you're optimizing, e.g. for code size (see codegolf x86-64 tips)


There is no magic in asm, each instruction only has its documented effect on the architectural state. (Contents of registers and memory).

As you can see from Intel's docs for call and ret, the only integer register they modify is RSP. Normal assemblers like NASM and GAS don't magically add instructions to your function. (MASM can be different, but if you look at disassembly you can still see the real code.)



来源:https://stackoverflow.com/questions/63865026/what-does-it-mean-that-registers-are-preserved-across-function-calls

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!