在我的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
答案 0 :(得分:2)
请注意,在amd64上,类UNIX操作系统(如Linux)通常遵循 sysV-ABI。除其他外,ABI指定如何将参数传递给函数。在带有SysV-ABI的amd64上,前几个参数在寄存器rdi
,rsi
和rdx
中传递。因此,当调用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的更多信息。