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

yvt65v4c  于 2022-11-24  发布在  其他
关注(0)|答案(1)|浏览(182)

假设函数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中的这个值如何在调用者和被调用者之间传递。

aamkag61

aamkag611#

为了说明这是如何工作的,我将使用函数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

相关问题