代码在这里:
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”中编译系统调用方式(我需要以这种方式调用系统调用程序)?
答案 0 :(得分:2)
您应该使用gcc -Wall
(也可能是-g
标志)进行编译。
这会给你更多的警告,并会指出一些容易出错的错误,例如缺乏适当的#include
exit(3)函数是一个库函数(使atexit
成为可能)。相应的系统调用是_exit(2),但在最近的Linux exit
上调用了exit_group(2)。所以你的例子错过了#include <stdlib.h>
当前的Linux实施通常不使用int 0x80
,而是通过VDSO或至少使用SYSENTER
或SYSCALL
机器指令。 YMMV。
您可以Jeremy answered使用asm
; (你可以为你正在使用的所有系统调用定义你自己的标题,让这些系统调用是static inline
函数做一些asm
)要注意,对于其他系统调用,你要捕获它们的失败和{{ 1}}错误代码。
你为什么要问?.... libc(和它的启动例程errno
...)正在做一些复杂的技巧来调用crt0.o
......
答案 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
机制以获得性能......
为什么要以过时的方式进行系统调用?