web-dev-qa-db-ja.com

アセンブリ言語でのアドレッシングモード(IA-32 NASM)

これに関するWebリソースはまばらなので、今後の検索のために、まずIA-32アセンブリ言語(NASM)のアドレスモードを一覧表示してから、簡単な質問を続けます。

  1. レジスタアドレス指定
    • mov eax、ebx:ebxにあるものをeaxにコピーします
    • mov esi、var:varのアドレス(たとえば0x0040120e)をesiにコピーします
  2. 即時アドレス指定(第2オペランドは即時定数)
    • mov bx、20:16ビットレジスタbxは実際の値20を取得します
  3. 直接メモリアドレス指定(指定されたアドレスを介してメモリから直接ロード)
    • mov ax、[1000h]:アドレス4096のバイト(16進数で0x1000)から「ax」と呼ばれる16ビットレジスタに2バイトのオブジェクトをロードします。
    • mov [1000h]、ax:アドレス1000hのメモリはaxの値を取得します
  4. 直接オフセットアドレス指定(3と同じ、算術演算を使用してアドレスを変更するだけ)
    • mov al、[byte_tbl + 2]
  5. レジスタ間接(レジスタに格納されているアドレスを使用してメモリにアクセスする)
    • mov ax、[di]:diで指定されたメモリアドレスの値をaxにコピーします
    • mov dword [eax]、var1:var1の値をeaxで指定されたメモリスロットにコピーします

上記はNASM用であることに注意してください。 MASM/TASMの場合、「mov esi、OFFSET foo」を使用してアドレスを取得し、「mov esi、foo」と「movesi、[foo]」の両方が値を取得します(@Michaelへのクレジット)。

だから、私の質問に。これは、次のチュートリアルの29ページの下部にある例に関連しています。 http://www.tutorialspoint.com/Assembly_programming/Assembly_tutorial.pdf

基本的に、間接メモリアドレス指定の例として以下のコードをリストします。

MY_TABLE TIMES 10 DW 0 ; Allocates 10 words (2 bytes) each initialized to 0 
MOV EBX, [MY_TABLE] ; Effective Address of MY_TABLE in EBX 
MOV [EBX], 110 ; MY_TABLE[0] = 110 
ADD EBX, 2 ; EBX = EBX +2 
MOV [EBX], 123 ; MY_TABLE[1] = 123 

私の質問:

  1. テーブルのアドレスを値自体ではなくEBXに入れたいので、「MOV EBX、[MY_TABLE]」を実際には「MOV EBX、MY_TABLE」にするべきではありませんか?
  2. 確かに、MY_TABLE [1]ではなく、最後に123に等しいのはMY_TABLE [2]ですか?
12
Magnus
  1. NASM構文では、その命令はMOV EBX, MY_TABLEである必要があります。 MOV EBX, [MY_TABLE]が行うことは、MY_TABLEにある最初の4バイトをEBXにロードすることです。もう1つの方法は、LEA EBX, [MY_TABLE]のように LEA を使用することです。

  2. この場合、チュートリアルは正しいです。 MY_TABLEは単語の配列として定義されます。 x86上のWordは2バイトであるため、MY_TABLEの2番目の要素は実際にはMY_TABLE + 2にあります。

6
Michael

そのチュートリアルは、有効なNASMコードでさえありません。 吸わないx86ガイド/リソース/マニュアルへのリンクについては、SOの x86タグwiki を参照してください。

MOV [EBX], 110どちらのオペランドもオペランドサイズを意味しない であるため、アセンブルされません。 (MASMでさえアセンブルしないと思いますが、emu8086のようないくつかの悪いアセンブラーには、このような命令のデフォルトのオペランドサイズがあります。)mov Word [ebx], 110は16ビットストアを実行します。

MOV EBX, [MY_TABLE]はアセンブルしますが、テーブルから最初の2ワードをロードします。 mov ebx, MY_TABLEはアドレスをレジスタに入れます。

0
Peter Cordes