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を変更して「int0x80」の方法でシステムコールをコンパイルできるようにするにはどうすればよいですか(I私のプログラムはこのようにsyscallを呼び出す必要があります)?

4

3 に答える 3

3

gcc -Wall(そしておそらく-gフラグも)コンパイルする必要があります。

これにより、より多くの警告が表示され、適切なものがないなど、簡単な間違いを特定できます。#include

exit(3)関数はライブラリ関数です(可能にしatexitます)。対応するシステムコールは_exit(2)ですが、最近のLinuxではexit_group(2)exitを呼び出しています。だからあなたの例は#include <stdlib.h>

現在のLinux実装は、多くの場合、VDSOを使用しないint 0x80が、VDSOを通過するか、少なくとも使用SYSENTERまたはSYSCALLマシン命令を実行します。YMMV。

ジェレミーが答えたように、あなたはasm;を使うことができます。(使用しているすべてのsyscallに対して独自のヘッダーを定義し、これらのsyscallstatic inlineをいくつかの実行関数にすることができasmます)他のsyscallについては、それらの失敗と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属性を使用して関数を宣言した場合にも、これが必要になることがありますnoreturn

__builtin_unreachable();
于 2013-03-27T08:14:29.667 に答える
1

システムコールはglibcによってラップされます。これは、基盤となるカーネルが使用するものをすべて使用する必要があります。Linuxはint 0x80、しばらく前にパフォーマンスのメカニズムから切り替えました...

なぜ時代遅れの方法でシステムコールをしたいのですか?

于 2013-03-28T02:50:01.643 に答える