6

我尝试用 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
4

2 回答 2

7

ia32 上的 Linux 不使用与 amd64 相同的调用约定。由于您的代码使用前者,您必须将其组装为 32 位并与 32 位 libc 链接。在 debian 上,您需要 libc6-dev-i386 软件包。

您还必须将 'call [printf]' 替换为 'call printf',这是错误的。

另请注意,当您使用主界面时,您应该从 main 返回,而不是执行退出系统调用以允许 C 运行时关闭代码运行。

带有构建说明的 x86-32 的 Hello World 示例

如果您正在使用 amd64,您可能想学习如何编写 64 位程序集。

带有构建说明的 x86-64 的 Hello World 示例

于 2012-08-02T21:24:12.973 回答
3

如果您真的想获得一个 32 位二进制文​​件,如代码标题所示,那么您只需要修复以下行:

call [printf]

将其更改为:

call printf

当你这样做时,call [printf]你不是调用 printf 而是调用第一个 printf 代码字节所指向的地址,该构造 ( [address]) 称为有效地址

于 2012-08-02T21:55:39.400 回答