2016-10-17 31 views
1

をコンパイルすることができますので、私はnasm -f elf final.asmを使用してアセンブリ内のいくつかのコードをアセンブルしようとしています:変換命令NASMがOK

次のエラーになり
xor eax,eax 
push eax 
push dword(0x75792273) 
push dword(0x70742027) 
push dword(0x77777875) 
push dword(0x20237678) 
push dword(0x76727827) 
push dword(0x27797175) 
push dword(0x75711225) 
push dword(0x72747676) 
push dword(0x74231476) 
push dword(0x70707470) 
push dword(0x23247077) 
push dword(0x78707822) 
push dword(0x24711174) 
push dword(0x22707373) 
push dword(0x78717974) 
push dword(0x75771777) 
push dword(0x70777125) 
push dword(0x73731472) 
push dword(0x71277377) 
push dword(0x79251822) 
push dword(0x79707478) 
push dword(0x78742779) 
push dword(0x72727871) 
push dword(0x71251475) 
push dword(0x27247772) 
push dword(0x79757479) 
push dword(0x70227071) 
push dword(0x77737420) 
push dword(0x70251970) 
push dword(0x74747127) 
push dword(0x23277677) 
push dword(0x79712024) 
push esp 
pop esi 
mov edi,esi 
mov edx,edi 
cld 
mov ecx,0x80 
mov ebx,0x41 
xor eax,eax 
push eax 
lods byte[esi] 
xor eax,ebx 
stos byte[es:edi] 
loop 0xb7 
push esp 
pop esi 
int 0x3 

final.asm:44: error: parser: instruction expected 
final.asm:46: error: parser: instruction expected 

これらのエラーの答えは、次の場所にあります。 NASM: parser: instruction expected rep movs

基本的に、これは、lodsとstosの指示はnoですNASMによって認識された。つまり、NASMが認識しているものに変換する必要があるので、同じ結果が得られます。

私の質問は、NASMが最終的にそれをデバッグできるようにNASMがコンパイルできるように、これらの2行を変更することができます。何lodsb

+2

変更。オペコードとオペランドの組み合わせが無効 test.asm:46:エラー:オペコードとオペランドの組み合わせが無効 – Jester

+0

を実行したときに、test.asm:44: edi] – ChrisMan

+0

lodsbバイト[esi] stosbバイト[es: – ChrisMan

答えて

2

は次のとおりです。

mov al,[esi] 
inc esi   ; (or dec, according to direction flag) 

あなたも(eaxに)ダブルワードをロードするために言葉(axに)、または
lodsdをロードするために
lodswを使用することができます。
esi

stosbここで

mov [es:edi],al 
inc edi 

同じ処理を行い、その場合には2、又は4だけ増加され、stosw及びstosdは2または4バイトメモリから

1の負荷を格納する、尖っSOURCE(ESI)レジスタによってDESTINATION(ES:EDI)レジスタが指すメモリに書き込みを行います。

使用するレジスタを指定する必要はありません()。ソースは常にE SなりI、およびセグメント・レジスタのデスティネーションは常にE D I


編集: lods命令は、セグメントオーバーライドプレフィックス(即ちss lodsb)と一緒に使用することができます。 stos命令はes(元の回答の詳細が欠落しています)セグメントの使用法に固定されており、上書きすることはできません。

movsb/movsw/movsd命令(size*(mov [es:edi],[ds:esi] inc esi inc edi))は、ソース側でオーバーライドすることもできます。 es movsbds:esiではなくes:esiからバイトをフェッチしますが、宛先セグメントレジスタはesに固定されています。

+0

@Pad7gもちろん、使用されるレジスタは 'al' ... not' ah'です!訂正のためのthx – Tommylee2k

2

Intel's LODS documentationは、オペランドをドキュメントとして使用でき、オペランドサイズのサフィックスの代わりに、操作しようとしているようにオペランドサイズ(およびセグメントのオーバーライド)を暗示することができます。

This explicit-operands form is provided to allow documentation; however, note that the documentation provided by this form can be misleading. That is, the source operand symbol must specify the correct type (size) of the operand (byte, word, or doubleword), but it does not have to specify the correct location. The location is always specified by the DS:(E)SI registers, which must be loaded correctly before the load string instruction is executed.

はおそらくNASMの文法の設計者はlods byte [r15]を組み立てることが可能ことは悪い考えであると判断しました、そして1オペランド形式を禁止することは、完全にだけ与えられたオペランドが、それは何であることを確認するために、コードの束を書くよりも簡単でした察するに。

NASMは、セグメント/オペランド/アドレスの上書きのための接頭辞構文を持っているので、fs lodsbは、あなたがそれ以外に、セグメントオーバーライドを添付するオペランドを必要とするものを書き込むことができます(MASM構文でlodsb fs:[rsi]同様。)

このようにそれをやってアセンブラに関する限り、文字列命令を特別なものにしません。それらは、ニーモニックをオペコードにマッピングするテーブル内の別のエントリに過ぎません。インテル独自のシンタックスでマシンコードプレフィックスバイトのニーモニックプレフィックスが含まれていた場合、同じデザインが選択されている可能性があります。

楽しい事実:STOSのセグメントを(ESから)上書きすることはできません。おそらく、インテルは、MOVSという8086の実装でより多くのトランジスタを共有したいと考えていました。セグメントのオーバーライドは[ES:DI]ではなく[DS:SI]ソースにのみ影響します。


他のアセンブラ

GNU .intel_syntaxは、セグメントプレフィックスの構文をサポートしていますが、ないNASMのo16/o32/o64またはa16/a32/a64オペランドとアドレスサイズ指定子。

# assembled with as --32 disassembled with ndisasm -b 32 
.intel_syntax noprefix 

    mov al, byte ptr fs:[esi] 
        00000038 648A06   mov al,[fs:esi] 

    gs lodsb 
        0000003B 65AC    gs lodsb 
    lods dword ptr ss:[ecx] 
    # Warning: `dword ptr ss:[ecx]' is not valid here (expected `[esi]') 
        0000003D 36AD    ss lodsd 
    ss lodsd [si] 
        0000003F 3667AD   ss a16 lodsd 
    lods eax, dword ptr ss:[esi] 
        00000042 36AD    ss lodsd 

#lods al  # Error: operand type mismatch for `lods' 
#fs es lodsd # Error: same type of prefix used twice 
#a16 lodsb # Error: no such instruction: `a16 lodsb' 

私は(& TまたはIntel AT)GNU構文のストリング命令の明示的なオペランドを使用せずに、アドレスサイズオーバーライドを書くための方法が表示されません。同一の

objdump -Mintel出力:単に `lodsb`と` stosb`(オペランドなし)に

4: 64 8a 06    mov al,BYTE PTR fs:[esi] 
    7: 65 ac     lods al,BYTE PTR gs:[esi] 
    9: 36 ad     lods eax,DWORD PTR ss:[esi] 
    b: 36 67 ad    lods eax,DWORD PTR ss:[si] 
    e: 36 ad     lods eax,DWORD PTR ss:[esi] 
+0

信じられないほど詳細。ありがとう、それは非常に情報的でした! – ChrisMan