18

私は現在、Linuxでアセンブリ言語を学んでいます。私は「ProgrammingFromtheGround Up」という本を使用してきましたが、すべての例は32ビットです。私のOSは64ビットで、すべての例を64ビットで実行しようとしています。しかし、私は問題を抱えています:

.section .data

.section .text
.global _start
_start:
movq $60, %rax
movq $2, %rbx
int $0x80

これは単にLinuxのexitSystem呼び出しを呼び出すだけであるか、そうすべきです。代わりに、SEG FAULTが発生し、代わりにこれを行うと

.section .data

.section .text
.global _start
_start:
movq $1, %rax
movq $2, %rbx
int $0x80

できます。明らかに問題は、%raxに移動する値です。2番目の例で使用する値$1は、「Programming From the Ground Up」が使用すると言ったものですが、インターネット上の複数のソースによると、64ビットのシステムコール番号は$60です。参照 私は何が間違っているのですか?また、他にどのような問題に注意する必要があり、参照用に何を使用する必要がありますか?あなたが知る必要がある場合に備えて、私はゼロからのプログラミングの第5章にいます。

4

5 に答える 5

20

i386とx86_64の驚くべき違いが1つあります。それらは、同じシステムコールメカニズムを使用していません。正しいコードは次のとおりです。

movq $60, %rax
movq $2,  %rdi   ; not %rbx!
syscall

割り込み0x80は常に32ビットのシステムコールを呼び出します。これは、32ビットアプリケーションを64ビットシステムで実行できるようにするために使用されます。

学習の目的で、64ビットにオンザフライで変換するのではなく、チュートリアルに正確に従うようにする必要があります。他にも、動作に大きな違いがいくつかあります。i386に慣れたら、x86_64を個別に入手できます。

于 2011-12-14T19:27:08.930 に答える
14

これを読んでくださいx86-64でのUNIXおよびLinuxシステムコールの呼び出し規約は何ですか

int 0x80また、x64システムでのsyscallの使用は、古い互換性レイヤーであることに注意してください。syscallx64システムでは命令を使用する必要があります。

この古い方法は引き続き使用できますが、バイナリをx86モードでコンパイルする必要があります。詳細については、コンパイラ/アセンブラのマニュアルを参照してください。

于 2011-12-14T19:26:34.797 に答える
7

duskwuff回答は、システムコールのメカニズムが64ビットx86Linuxと32ビットLinuxで異なることを正しく指摘しています。

ただし、この回答はいくつかの理由で不完全で誤解を招く可能性があります。

コメントで指摘されているようにSYSENTER 実際には多くの64ビットLinuxシステム(つまり64ビットAMDシステム)では機能しません。

それは確かに紛らわしい状況です。残酷な詳細はここにありますが、結局のところこれは次のとおりです。

32ビットカーネルの場合、SYSENTER/SYSEXITが[AMDとIntelCPUの間の]唯一の互換性のあるペアです。

ロングモードの64ビットカーネルの場合のみ…SYSCALL/SYSRETが[AMDとIntelCPU間の]唯一の互換性のあるペアです。

64ビットモードのIntelCPUでは、と同じことを行うため、使用をやめることができるようですが、 AMDシステムの場合はそうではありません。SYSENTERSYSCALL

結論:64ビットx86システム上のLinuxで常に使用SYSCALLします。これは、x86-64ABIが実際に指定しているものです。(詳細については、このすばらしいWikiの回答を参照してください。)

于 2015-07-20T06:53:28.500 に答える
5

i386とx86_64の間で、カーネルに入るのに使用される命令とシステムコール引数を運ぶために使用されるレジスタの両方を含め、かなり多くの変更がありました。これがあなたと同等のコードです:

.section .data

.section .text
.global _start
_start:
movq $60, %rax
movq $2, %rdi
syscall

この回答から関連する質問への引用:

システムコール番号は、Linuxソースコードのarch / x86 / include / asm/unistd_64.hにあります。システムコール番号はraxレジスタに渡されます。パラメータは、rdi、rsi、rdx、r10、r8、r9にあります。呼び出しは「syscall」命令で呼び出されます。システムコールはrcxレジスタを上書きします。リターンはラックスです。

于 2011-12-14T19:42:10.797 に答える
3

チェック/usr/include/asm/unistd_32.hすると、exitはに対応します1が、 /usr/include/asm/unistd_64.hexitではに対応し60ます。

于 2012-09-29T15:43:11.660 に答える