函数调用如何在x86-64汇编中返回值?



假设我有一个函数foo定义为:

def foo(x,y):
return x + y

说我有一个函数调用:

foo(2,3)

对应于x86-64:

movq $2 %rdi
movq $3 %rsi
call foo

我知道,如果函数foo有一个返回值,它将存储在寄存器%rax中。但这到底是什么意思呢?

程序集应该是这样的:

movq $2 %rdi
movq $3 %rsi
call foo
foo:
movq -8(%rsb) %rax
addq -16(%rsb) %rax

你能在汇编中完成foo的定义吗?它使用%rax吗?如何使用%rax?

我的问题是如何使用%rax来获得函数的返回值以及%rax中的此值如何在调用者和被调用者之间传递。由于

为了说明这是如何工作的,我将使用函数foo作为示例:

def foo(x,y):
return x + y
main:
z = foo(7,10) * 3

那么z的值是如何计算的。(实际发生的情况可能是编译器会预先计算17*3并将其作为常量加载,但这对我试图演示的内容没有帮助。)

main:
mov  $7, %edi       # put integer args in 64-bit registers efficiently
mov  $10, %esi      # with zero-extension of 32-bit
call foo      
#the ret instruction at the end of "foo" takes us back here
#the result of "foo" is now in %rax, and the rest of the program can use it.
mov %rax, %rdx    # Save a copy of %rax so we can multiply by 3.
shl $1, %rax      # multiply by 2
add %rdx, %rax    # add the original, this means we effectively multiplied by 3.
# lea (%rax, %rax, 2), %rax   # efficient way to multiply by 3
ret              # exit program by returning from main()
####################################################
foo:
add %rsi, %rdi    # add the two numbers
mov %rsi, %rax    # return value in %rax
ret
# compilers would have used  lea (%rdi, %rsi), %rax  to copy-and-add

最新更新