Reputation: 41
I am working with a simple assembly snippet to print a character to screen using the BIOS as a part of a bootloader. Here is the bootloader code.
[org 0x7c00]
[bits 16]
%include "a20_check.asm"
mov ah, 0x0e
mov al, 'H'
int 0x10
times 510 - ($-$$) db 0
dw 0xaa55
This is the code for the a20_check.asm function, taken from osdev.org.
[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
The problem appears to be in the last label, check_a20__exit. If I comment out ret
, then the character prints to the screen. Otherwise, it does not print.
Can someone explain this problem to me?
Upvotes: 4
Views: 225
Reputation: 16331
If you think about your own description of your troubleshooting and then look at how you've included the code, it should be obvious what the problem is.
ret
Obviously, the ret
is going to try to use whatever's currently at SP
and switch the execution path there... but you've never called anything, so that data is just garbage.
Removing the ret
allows it to "fall through" to your printing code.
Upvotes: 4