让gcc以“int 0x80”的方式编译系统调用?

时间:2013-03-27 08:06:21

标签: c linux gcc assembly system-calls

代码在这里:

void main()
{
    _exit(0);
}

通过拆卸主要部分:

 80483d4:   55                      push   %ebp
 80483d5:   89 e5                   mov    %esp,%ebp
 80483d7:   83 e4 f0                and    $0xfffffff0,%esp
 80483da:   83 ec 10                sub    $0x10,%esp
 80483dd:   c7 04 24 00 00 00 00    movl   $0x0,(%esp)
 80483e4:   e8 17 ff ff ff          call   8048300 <_exit@plt>

据我所知,制作系统调用的方法是使用“int 0x80”,但我可以在这里找到“调用8048300 exit @ plt”,那么如何更改gcc以使其在“int 0x80”中编译系统调用方式(我需要以这种方式调用系统调用程序)?

3 个答案:

答案 0 :(得分:2)

您应该使用gcc -Wall(也可能是-g标志)进行编译。

这会给你更多的警告,并会指出一些容易出错的错误,例如缺乏适当的#include

exit(3)函数是一个库函数(使atexit成为可能)。相应的系统调用是_exit(2),但在最近的Linux exit上调用了exit_group(2)。所以你的例子错过了#include <stdlib.h>

当前的Linux实施通常不使用int 0x80,而是通过VDSO或至少使用SYSENTERSYSCALL机器指令。 YMMV。

您可以Jeremy answered使用asm; (你可以为你正在使用的所有系统调用定义你自己的标题,让这些系统调用是static inline函数做一些asm)要注意,对于其他系统调用,你要捕获它们的失败和{{ 1}}错误代码。

你为什么要问?.... libc(和它的启动例程errno ...)正在做一些复杂的技巧来调用crt0.o ......

另见this answer

答案 1 :(得分:2)

对于32位

asm( "int $0x80" :: "a" (1), "b" (0) );

表示64位

asm( "syscall" :: "a" (60), "D" (0) );

如果您已声明属性为exit的{​​{1}}函数,则可能还需要此功能。

noreturn

答案 2 :(得分:1)

系统调用由glibc包装,glibc应该使用底层内核使用的任何内容。 Linux暂时退出int 0x80机制以获得性能......

为什么要以过时的方式进行系统调用?