0

代码在这里:

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”,但我可以在这里找到“call 8048300 exit@plt”,那么我该如何更改 gcc 让它以“int 0x80”方式编译系统调用(我需要我的程序以这种方式调用系统调用)?

4

3 回答 3

3

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

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

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

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

正如杰里米回答的那样,您可以使用asm; (您可以为正在使用的所有系统调用定义自己的标头,并让这些系统调用成为static inline执行某些操作的函数asm)请注意,对于其他系统调用,您希望捕获它们的失败和errno错误代码。

你为什么要问?.... libc(及其启动例程crt0.o...)正在使用复杂的技巧来调用main...

另请参阅此答案

于 2013-03-27T08:13:34.507 回答
2

对于 32 位

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

对于 64 位

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

如果你已经exit用 attribute 声明了你的函数,你可能还需要这个noreturn

__builtin_unreachable();
于 2013-03-27T08:14:29.667 回答
1

系统调用由 glibc 包装,它应该使用底层内核使用的任何内容。Linux 不久前放弃了int 0x80性能机制......

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

于 2013-03-28T02:50:01.643 回答