int 80不出现在汇编代码中

时间:2015-08-17 17:38:48

标签: c system-calls

问题

让我们考虑一下:

int main(){
write(1, "hello", 5);
return 0;
}

我正在读一本书,建议上面代码的汇编输出应该是:

main:
mov $4, %eax
mov $1 %ebx
mov %string, %ecx
mov $len, %edx
int $0x80

(上面的代码是用32位架构编译的。通过寄存器传递参数不是由'64位约定通过寄存器传递参数引起的,但它是由事实引起的,我们进行了系统调用。)

我的64位Ubuntu机器上的输出:gcc -S main.c -m32 是:

pushl   $4
pushl   $string
pushl   $1
call    write

我的疑惑

所以它让我很困惑。为什么gcc将其编译为“正常”调用,而不是作为系统调用。 在这种情况下,使处理器使用内核函数(如write)的方法是什么?

1 个答案:

答案 0 :(得分:4)

  

我正在读一本书,建议上面代码的汇编输出应该是......

你不应该相信你读到的一切: - )

没有要求将C代码转换为特定的汇编代码,C标准要求的唯一要求是生成的代码以某种方式运行。

是否通过直接使用int $80(或sysenter)调用OS系统调用来完成,或者是否通过调用库例程write()来完成最终以类似的方式调用操作系统,这在很大程度上是无关紧要的。

如果您要查找和反汇编write()代码,您可能会发现它只是将堆栈中的值读取到寄存器中,然后以与您显示的代码相同的方式调用操作系统int $80

顺便说一下,如果您想将gcc移植到使用call 5进行操作系统级系统调用的完全不同的架构,该怎么办?如果gcc正在将特定的int $80调用注入到程序集流中,那么这将无法正常工作。

但是,如果它正在向write()函数注入一个调用,那么您所要做的就是确保将它与包含已修改write()函数的正确库链接({{1}而不是call 5)。