2017-07-12 10 views
3

私はシンプルなアセンブリスニペットを使用して、BIOSをブートローダーの一部として使用してスクリーンに文字を印刷しています。ここにブートローダーコードがあります。アセンブリBIOSコールが動作しない

[org 0x7c00] 

[bits 16] 

%include "a20_check.asm" 


mov ah, 0x0e 
mov al, 'H' 
int 0x10 

times 510 - ($-$$) db 0 
dw 0xaa55 

これはosdev.orgから採取a20_check.asm機能、ためのコードです。

[bits 16] 


; Returns: 0 in ax if the a20 line is disabled (memory wraps around) 
;   1 in ax if the a20 line is enabled (memory does not wrap around) 

check_a20: 
pushf 
push ds 
push es 
push di 
push si 

cli 

xor ax, ax ; ax = 0 
mov es, ax 

not ax ; ax = 0xFFFF 
mov ds, ax 

mov di, 0x0500 
mov si, 0x0510 

mov al, byte [es:di] 
push ax 

mov al, byte [ds:si] 
push ax 

mov byte [es:di], 0x00 
mov byte [ds:si], 0xFF 

cmp byte [es:di], 0xFF 

pop ax 
mov byte [ds:si], al 

pop ax 
mov byte [es:di], al 

mov ax, 0 
je check_a20__exit 

mov ax, 1 

check_a20__exit: 
pop si 
pop di 
pop es 
pop ds 
popf 

ret 

問題は、最後のラベルにcheck_a20__exitように見えます。私がretをコメントアウトすると、文字が画面に印刷されます。それ以外の場合は、印刷されません。

誰かがこの問題を私に説明できますか?

+0

"mov ax、1"の後ろに "check_a20__exit"の最後の行を越えてジャンプするジャンプコードを書くべきでしょう。私の理論は、コードが "je check_a20__exit"という行から "check_a20__exit"にジャンプしていないということです"je check_a20__exit"の直後に "check_a20__exit"がラベルであり、C++のような関数ではないので、 "check_a20__exit"も実行されます。したがって、ret文は、以前に一致するジャンプなしで呼び出されます。 "je check_a20__exit"命令の直前のゼロフラグの値を確認してください。 –

+0

このコードが実行されているH/W環境はどれですか? "mov ax、0"はアキュムレータレジスタをゼロにしてゼロフラグを設定しようとしています。 –

+0

コードは、i386アーキテクチャを使用してqemuエミュレーションを使用して実行されています。 – micronchip

答えて

4

あなたのトラブルシューティングの説明を考えて、コードをどのように組み込んでいるかを見てみると、問題が何であるかがはっきりしているはずです。

  • まず、あなたは、このコードは、我々は最終的に我々はヌルパディングを持って画面
  • に文字を印刷したコードを見つけるret
  • 次で終わるA20ライン
  • をチェックするためのコードを含ん
  • 明らかに

は、retSPで、現在、何でも使用して、そこに実行パスを切り替えようとしている...しかし、あなたはanytと呼ばれることがありませんヒンジは、データがちょうどゴミになるようにします。

retを削除すると、それが印刷コードに落ちることがあります。

+3

文字を印刷した後に言及する以外に、何も指定されていない場所でコードを実行し続けます(潜在的にメモリを放棄します)。それを避けるために何らかの無限ループを張るべきです。 –

関連する問題