【发布时间】:2018-06-12 18:25:36
【问题描述】:
我正在尝试在 nasm 中创建一个应该显示字母 a 的简单程序。但是,它给了我一个 Segfault 并说:
./a.out: Symbol `printf' causes overflow in R_X86_64_PC32 relocation
Segmentation fault (core dumped)
基本上,我试图将值 0x61(字母 a 的十六进制)移动到内存地址 1234,然后将其作为参数传递给 printf。这是我的确切代码:
extern printf
section .text
global main
main:
push rbp
mov rax,0
mov qword [1234], 0x61 ; move 0x61 into address 1234
mov rdi, qword [1234] ; mov address 1234 into rdi
call printf ; should print the letter a
pop rbp
mov rax,0
ret
我正在运行 Linux x86_64
【问题讨论】:
-
内存地址 1234 在 Linux 上几乎可以肯定是不可写的。
Printf将格式字符串作为第一个参数。在这段代码中看不到任何这样的格式字符串。 -
在与位置无关的 64 位代码中对
printf的调用应该类似于call [printf wrt ..got] -
printf 可以不带格式字符串调用
-
总是有一个格式字符串。如果您只是打印一个字符串,则格式是实际的字符串。如果要打印单个字符,可以使用格式说明符
"%c",第二个参数是要打印的字符。或者你想创建一个包含单个字符的 NUL 终止字符串? -
这样的事情可能会起作用:
default rel ; Use RIP relative addressing by default.main: xor eax, eaxpush 0x61 ; Push 0x61 onto stack followed by 7 bytes of 0x00lea rdi, [rsp] ; Address of character a on stackcall [printf wrt ..got]add rsp, 8 ; restore stackxor eax,eax ; return 0ret
标签: linux gcc segmentation-fault nasm x86-64