如何在汇编程序x86-64中将参数(由C函数调用传递)保存到全局变量?

时间:2017-03-23 14:25:55

标签: assembly x86-64

在我的test.c文件中:

size_t var = 1000;
foo(var);
在test.h中

int *foo(size_t var);

在test.asm中:

global foo
section .bss
    N: resd 0
; ...
foo:
    ; how can I get to "var" here and how can I write it to "N"?

我尝试写过类似的东西:

push    rbp
mov     rbp, rsp
mov     rax, [rbp+8]
mov     [N], rax
pop     rbp
ret

mov [N], rdi
ret

...但在这两种情况下我都会得到"分段错误(核心转储)"错误,事实上,我甚至不确定这里发生了什么。我使用的是nasm和gcc。这是一个我无法开始工作的简短版本:http://pastebin.com/WELNeRXy

1 个答案:

答案 0 :(得分:2)

请注意,在amd64上,类UNIX操作系统(如Linux)通常遵循 sysV-ABI。除其他外,ABI指定如何将参数传递给函数。在带有SysV-ABI的amd64上,前几个参数在寄存器rdirsirdx中传递。因此,当调用foo时,调用方会将var放入rdi。所以正确的代码是这样的:

foo:
    mov [N],rdi
    ret

为了便于与位置无关的代码,您可能还需要使用指令指针相对寻址模式。这是使用rel关键字完成的:

foo:
    mov [rel N],rdi
    ret

进一步注意,您实际上需要为N分配八个字节的存储空间。将N的定义更改为以下内容:

    section .bss
N:  resq 1

N保留一个四字(8字节)。

您可以在其他地方找到有关SysV ABI的更多信息。

相关问题