質問

私はゼロからアセンブリを学ぼうとしています。私はかなり読んでいますが、参考書で見つけた以下の簡単なプログラムでさえ、私は困惑しています:

section .data
msg db "Hello!", 0xa
len equ $ - msg
section .text

     global _start

_start:


move edx, len
move ecx, msg
move ebx, 1
move eax, 4
int  0x80
move ebx, 0
move eax, 1
int 0x80

どうやらこれは「Hello」を印刷することになっています。しかし、私はどの段階でも何が起こっているのかさえ知りません。最初の2つのステージでは、メッセージの長さとメッセージを2つのレジスタに配置しますが、これは二度と使用されません。理由がわかりません。

4つの異なるレジスタが必要な理由はわかりません。

役に立ちましたか?

解決

int 80 いくつかのメカニズムです*a システムコールを作成するためのUNIXのようなオペレーティングシステム。

これらの呼び出しでは、レジスタは特定の値に使用されます。から syscalls ファイル:

0 STD NOHIDE { int nosys(void); } syscall nosys_args int
1 STD NOHIDE { void exit(int rval); } exit rexit_args void
2 STD POSIX  { int fork(void); }
3 STD POSIX  { ssize_t read(int fd, void *buf, size_t nbyte); }
4 STD POSIX  { ssize_t write(int fd, const void *buf, size_t nbyte); }

4番があることがわかります write 他の3つのパラメーターを呼び出して必要です。ナンバー1です exit また、返品コードのみが必要です。

電話をかけるとき、 eax あなたがしばらく作っているsyscallです ebx, ecxedx 3つのパラメーターです(それらがすべて必要であると仮定します - exit たとえば、1つだけが必要です)。

したがって、次のようにコードにコメントできます。

move edx, len   ; length of message (nbyte).
move ecx, msg   ; message to print (buf).
move ebx, 1     ; file handle 1, stdout (fd).
move eax, 4     ; write syscall.
int  0x80       ; do it.

move ebx, 0     ; exit code (rval).
move eax, 1     ; exit syscall.
int 0x80        ; do it.

*A: Linuxの後のバージョンでは、最高の速度を提供するさまざまな方法を使用して、新しいインターフェイスを導入しました。たとえば、一部のIntelチップは、使用するとはるかに高速です sysenter それよりも int 80.

他のヒント

iirc int 0x80 命令は、割り込みベクトルを使用してsyscallを呼び出すために使用されます。あなたの例では、値は ebxeax どのsyscallを呼び出すかを指定するために使用されます(おそらくstdoutの印刷操作)。

syscallはそれを召集することで知っています edxecx 印刷されるものを含める必要があります。

多くのシステムで、 int 80h それは システムコール ゲート。 syscall番号があります eax. ebx, ecxedx 追加のパラメーターが含まれています:

move edx, len
move ecx, msg
move ebx, 1    ; fd 1 is stdout
move eax, 4    ; syscall 4 is write
int  0x80      ; write(1, msg, len)
move ebx, 0
move eax, 1    ; syscall 1 is exit
int 0x80       ; exit(0)

システムコール、「int」ニーモニックを呼び出すと、システムの中断が生成されます。これは、システム関数に「ジャンプ」します。この場合、出力を印刷します(EAXに依存します)。

この中断は、これらすべてのレジスタを使用して、何をすべきかを知ります。割り込みはEAXを読み取り、必要な関数を確認し、他のレジスタを使用してそうするようにします。

EAXは関数番号です。4つはSYS_WRITEを意味し、ストリーム/ファイル記述子に文字列を書き込みます。

今では、ある場所に何かを書きたいと思っていることがわかっているので、他のレジスタをそれらの情報に使用します。

EAX = 4およびint 0x80の場合、これは他のレジスタの意味です。

ebx = output(1 = stdout)
ECX =文字列のアドレス
edx =文字列の長さ

あなたはこれを読むことができます:

http://www.intel.com/assets/ja_jp/pdf/manual/253665.pdf

セクション6.4は、中断と例外についていくつかのものがあります。

また、Intel 80x86アセンブリコードの書き込みを開始できます。これはよりシンプルで理解しやすいです。ここにリンクがあります。

nnemonics/codeテーブルチートシート:http://www.jegerlehner.ch/intel/

いくつかの紹介サイト:http://mysite.du.edu/~etuttle/math/8086.htmhttp://www.malware.org/teaching/assembly.htm

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top