micronchip
micronchip

Reputation: 41

Assembly BIOS call not working

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

Answers (1)

David Hoelzer
David Hoelzer

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.

  • First, you include your code for checking the A20 line
  • That code ends with a ret
  • Next we find the code that prints a character on the screen
  • Finally we have null padding

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

Related Questions