我刚刚开始在Linux上学习/使用Assembly x64,并试图用getcwd()
调用call
。尝试调用getcwd()
函数后,我也试图输出不起作用的结果,并且我不明白为什么。任何指针/帮助将不胜感激。抱歉,这是一个愚蠢的问题。我在网上寻找示例,但没有找到任何对我有帮助的示例。非常感谢。这是代码:
section .text
global _start
extern getcwd
_start:
mov rdi,rbx
mov rsi,128
call getcwd wrt ..plt
mov rax,1
mov rdi,1
mov rsi,rbx
mov rdx,128
syscall
mov rax,60
mov rdi,0
syscall
我编译为:
nasm -f elf64 -o file.o file.asm
gcc -nostdlib -v -o file file.o -lc
./file
没有显示任何内容
这里是一个可能的实现,它在堆栈上分配空间。我也切换到了main
和puts
:
global main
extern getcwd
extern puts
main:
sub rsp, 128+8 ; buffer + alignment
mov rdi, rsp
mov rsi, 128
call getcwd wrt ..plt
call puts wrt ..plt
add rsp, 128+8
ret
此代码
mov rdi,rbx
mov rsi,128
call getcwd wrt ..plt
等效于C代码getcwd(__undefined__, 128);
,其中__undefined__
是在输入ebx
时恰好在_start
中的某个值。在我的系统上,它似乎是NULL
,getcwd
表示没有缓冲区通过(无论其大小为128)。
getcwd
函数然后返回指向新分配的缓冲区的指针(作为POSIX的扩展,请参见man 3 getcwd
)。后续的mov rax,1
用系统调用覆盖该地址,随后的指令将ebx
中的值作为缓冲区传递给write
系统调用。因为以前是NULL
,所以根据调用约定,它仍然是这样,而您调用write(1,NULL,128);
,则它返回EFAULT
并且不写任何内容。