【发布时间】:2012-07-31 21:18:04
【问题描述】:
我尝试用 printf 函数编写简单的汇编程序。我编译它nasm -f elf 64 并使用gcc 链接。运行后我看到segmentation fault。怎么了?
[Bits 32]
extern printf
global main
section .data
hello:
db "Hello", 0xa, 0
section .text
main:
push hello
call [printf]
add esp, 4
mov eax, 1
mov ebx, 0
int 80h
【问题讨论】:
-
为什么要把一个明明是32位的程序组装成
elf64? -
因为当我不这样做时,我会看到:
/usr/bin/ld: i386 architecture of input file ./asemlebr.o is incompatible with i386:x86-64 output -
你在哪里写
printf?如果您正在考虑调用 C 库中的那个,那将需要更多的工作 - 您需要确保调用库的初始化代码,根据您所在平台的 ABI,并将您的程序与库链接,至少... -
@twalberg:实际上这可以正常工作。 OP 正在编写
main,因此即使在静态可执行文件中,CRT 启动代码也会在调用 main 之前初始化 glibc。在与 glibc 的动态 链接二进制文件中,_start也是安全的,因为动态链接器使用与在 C++ 库代码中运行静态初始化程序相同的机制调用 glibc 的 init 函数。相关:stackoverflow.com/questions/36861903/… 了解更多关于静态与动态二进制文件以及是否链接 libc 的信息。 -
这里的主要危险是
sys_exit不会刷新标准输出,但如果它不是 TTY,它将是全缓冲的。