【发布时间】:2016-02-02 15:10:31
【问题描述】:
我刚开始学习 x86 汇编,我有点困惑为什么这个小例子不起作用。我要做的就是将 eax 寄存器的内容打印为十进制值。这是我在 AT&T 语法中的代码:
.data
intout:
.string "%d\n"
.text
.globl main
main:
movl $666, %eax
pushl %eax
pushl $intout
call printf
movl $1, %eax
int $0x80
我编译运行如下:
gcc -m32 -o hello helloworld.S
./hello
这是例外情况(将 666 打印到控制台)。顺便说一句,我想指出我不明白 "movl $1, %eax" 和 "int $0x80" 到底应该做什么在这里完成。我也不确定 "pushl $intout" 做了什么。为什么我的输出由两个单独的堆栈条目组成? .string 宏到底是做什么的?
不过,这些只是附带问题,因为我的真正问题是我找不到使用更容易读/写/理解 Intel 语法来运行此程序的方法。
代码如下:
.intel_syntax noprefix
.data
intout:
.string "%d\n"
.text
.globl main
main:
mov eax, 666
push eax
push intout
call printf
mov eax, 1
int 0x80
和上面一样运行,它只是打印“Segmentation fault”。
我做错了什么?
【问题讨论】:
-
其实不推荐使用
movl $1,%eax; int $0x80。如果您按原样使用 C 库,则应该只使用call exit。或者你可以ret,假设你正确地清理了你没有做的堆栈。您有 2 个条目,因为您传递了 2 个参数(格式字符串和数字)。至于.string做了什么,我想你可以猜到,或者,你知道的,阅读manual。 -
int 0x80和call exit有什么区别?
-
前者是直接的系统调用,没有机会让 C 库正常关闭。而且它的便携性也较差。
-
所以 C 库基本上把它抽象掉了,基于它编译的系统?
标签: gcc assembly x86 segmentation-fault printf