私は十分にグーグルで検索しましたが、角かっこが何()
を意味するのか理解できませんでした。また、私はいくつかの構文を次のように見ていますmovl 8(%ebp), %eax
誰かが私にいくつかの良い参考文献を提案できますか?Googleの上位20件の結果から何も見つかりませんでした。
私は十分にグーグルで検索しましたが、角かっこが何()
を意味するのか理解できませんでした。また、私はいくつかの構文を次のように見ていますmovl 8(%ebp), %eax
誰かが私にいくつかの良い参考文献を提案できますか?Googleの上位20件の結果から何も見つかりませんでした。
%eax
レジスタEAXです。(%eax)
アドレスがレジスタEAXに含まれているメモリ位置です。8(%eax)
は、アドレスがEAXに8を加えた値であるメモリ位置です。
http://web.archive.org/web/20080215230650/http://sig9.com/articles/att-syntaxは、Unix (AT&T) asm 構文の簡単な紹介です。によってググられましたat&t asm syntax
。
この投稿は、vivek ( http://web.archive.org/web/20080228052132/http://sig9.com/blog/vivek )、2003-09-01 による「AT&T Assembly Syntax」です。そこから AT&T に関する主な情報があります。
たとえば、INTEL 構文の基本的なデータ移動命令の一般的な形式は次のとおりです。
mnemonic destination, source
一方、AT&T の場合、一般的な形式は次のとおりです。
mnemonic source, destination
(この順序は、AT&T asm を本物の Unix asm と呼んでいることを覚えています。したがって、これは正しいものであり、データは右側に流れます。Intel の構文は、Unix の世界には明らかに正しくない、誤った masms doc に基づいていましたが、左に、データは左に流れます)
IA-32 アーキテクチャのすべてのレジスタ名には、'%' 記号を前に付ける必要があります。%al、%bx、%ds、%cr0 など
すべてのリテラル値の前に「$」記号を付ける必要があります。例えば、
mov $100, %bx mov $A, %al
最初の命令は値 100 をレジスタ AX に移動し、2 番目の命令は ascii A の数値を AL レジスタに移動します。
AT&T 構文では、メモリは次のように参照されます。
segment-override:signed-offset(base,index,scale)
必要なアドレスに応じて一部を省略できます。> %es:100(%eax,%ebx,2)
オフセットとスケールの前に「$」を付けないでください。同等の NASM 構文を使用したさらにいくつかの例は、物事をより明確にするはずです。
GAS memory operand NASM memory operand ------------------ ------------------- 100 [100] %es:100 [es:100] (%eax) [eax] (%eax,%ebx) [eax+ebx] (%ecx,%ebx,2) [ecx+ebx*2] (,%ebx,2) [ebx*2] -10(%eax) [eax-10] %ds:-10(%ebp) [ds:ebp-10] Example instructions, mov %ax, 100 mov %eax, -100(%eax)
オペランドのサイズ。特にリテラル値をメモリに移動する場合、転送サイズまたはオペランド サイズの指定が必要になることがあります。たとえば、指示、
mov $10, 100
値 10 をメモリ オフセット 100 に移動するように指定するだけで、転送サイズは指定しません。NASM では、キャスト キーワード byte/word/dword などを任意のオペランドに追加することでこれを行います。AT&T 構文では、命令にサフィックス (b/w/l) を追加することでこれを行います。例えば、
movb $10, %es:(%eax)
バイト値 10 をメモリ位置 [ea:eax] に移動しますが、
movl $10, %es:(%eax)
long 値 (dword) 10 を同じ場所に移動します。
jmp、call、ret などの命令は、制御をプログラムのある部分から別の部分に移します。これらは、同じコード セグメントへの制御転送 (near) または別のコード セグメントへの制御転送 (far) として分類できます。分岐アドレッシングの可能なタイプは、相対オフセット (ラベル)、レジスタ、メモリ オペランド、およびセグメント オフセット ポインタです。
相対オフセットは、以下に示すように、ラベルを使用して指定されます。
label1: . . jmp label1
レジスタまたはメモリ オペランドを使用した分岐アドレス指定には、'*' をプレフィックスとして付ける必要があります。"far" 制御転送を指定するには、'ljmp'、'lcall' などのように、'l' を前に付ける必要があります。たとえば、
GAS syntax NASM syntax ========== =========== jmp *100 jmp near [100] call *100 call near [100] jmp *%eax jmp near eax jmp *%ecx call near ecx jmp *(%eax) jmp near [eax] call *(%ebx) call near [ebx] ljmp *100 jmp far [100] lcall *100 call far [100] ljmp *(%eax) jmp far [eax] lcall *(%ebx) call far [ebx] ret retn lret retf lret $0x100 retf 0x100
セグメント オフセット ポインターは、次の形式を使用して指定されます。
jmp $segment, $offset
彼はまた、gnu as (gas) docs を推奨しています: http://web.archive.org/web/20080313132324/http://sourceware.org/binutils/docs-2.16/as/index.html
それらは移動命令であり、ある場所から別の場所にデータを移動します。これらの場合は、メモリからレジスタに移動します。
register_eax = *(unsigned long *)register_eax;
あなたの他の例は次のようなものです:
register_eax = *(unsigned long *)(register_ebp + 8);