2017-04-27 18 views
2

単一ワード(2バイト)を比較するときにCMP命令で問題が発生します。
次は私の明main.asmです:x86 CMP命令が単一ワード比較で機能しない

print_string: 
    pusha 
    mov ah, 0x0e 
    loop: 
     call print_char 
     cmp word [bx], 0 
     jne loop 
    popa 
    ret 

print_char: 
    mov al, [bx] 
    int 0x10 
    add bx, 1 
    ret 

このコードは、次を出力:

こんにちはこれはprint_string.asmファイルです

[org 0x7c00] 

mov bx, HELLO_MSG 
call print_string 

mov bx, GOODBYE_MSG 
call print_string 

jmp $ 

%include "print_string.asm" 

; Data 
HELLO_MSG: 
    db 'Hello, World!', 0 
GOODBYE_MSG: 
    db 'Goodbye!', 0 

世界!さようなら!さようなら!

私はHELLO_MSGGOODBYE_MSGの間で

db 0 

を追加するときに意図したとおり、コードが動作することを知っています。誰も理由を説明することができますCMPは、文字列の間に0の4バイトがある場合にのみ動作しますか?

誰もがコンパイルされた出力を見に興味がある場合は、ここにある:

bb 23 7c e8 08 00 bb 31 7c e8 02 00 eb fe 60 b4 
0e e8 07 00 83 3f 00 75 f8 61 c3 8a 07 cd 10 83   
c3 01 c3 48 65 6c 6c 6f 2c 20 57 6f 72 6c 64 21 
00 47 6f 6f 64 62 79 65 21 00 00 00 00 00 00 00   
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
*   
00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa 

私はブートローダとして、このコードを使用していますので、最後に55 aaは、私が追加されます。

+5

アドレス 'bx'から始まる2バイトを比較する' cmp word [bx]、0'を実行しています。おそらく1バイトを比較したいと思うでしょう。 'cmp byte [bx]、0' –

+0

また、セグメントレジスタとスタックなどを適切に設定することをお勧めします。この一般的なブートローダのヒントを持つこのStackoverflow答えのヒントをいくつか挙げます(http://stackoverflow.com/a/ 32705076/3857942) –

+1

また、print_stringに_BX_以外のレジスタを使用することもできます。 [_Int 10/AH = 0Eh_](http://www.ctyme.com/intr/rb-0106.htm)は、書き込むページ番号として_BH_を使用します。これを0に設定するとよいでしょう。つまり、_BX_以外のレジスタを文字列ポインタとして使用する必要があります。たぶん_SI_であろう。 –

答えて

3

ワードが2バイトを含まなければならないため、CMP命令がシングルワード比較のために機能しない理由があります。以来コンパイル出力は二つのメッセージ間の唯一の1バイトがあることを示して、あなたはバイトに単語からCMP命令のサイズを変更する必要があります。

cmp byte [bx], 0 

私は、コンパイル済みの出力形式と仮定してのミスを犯しました

ライン4つの00 47 6Fで始まり、これらの値(スペースで区切っ)のそれぞれが単一バイトではなく、2:マイケル・ペッチによって、次のコメントの助けを借りて、しかし2でバイトを配置しバイト。 00は0の1バイトであり、2バイトではありません。

私は間違いを実感できました。

+0

➕1であり、間違いから学び、あなた自身の質問に答えます。 –

関連する問題