私はシンプルなアセンブリスニペットを使用して、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
をコメントアウトすると、文字が画面に印刷されます。それ以外の場合は、印刷されません。
誰かがこの問題を私に説明できますか?
"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"命令の直前のゼロフラグの値を確認してください。 –
このコードが実行されているH/W環境はどれですか? "mov ax、0"はアキュムレータレジスタをゼロにしてゼロフラグを設定しようとしています。 –
コードは、i386アーキテクチャを使用してqemuエミュレーションを使用して実行されています。 – micronchip