I've been struggling with this problem I run into when I try to run some code on my real hardware. I've tried lots of possible solutions but I won't exclude I could have been missing something obvious.
SSCCE
Code: Select all
.code16
.global _start
.equ ORG_SEGMENT, 0x0
.text
_start:
cli
jmp $ORG_SEGMENT, $(asmain) # setting up CS:IP
asmain:
xor %ax, %ax
mov %ax, %ds # data-segment needs to be set up for data access
mov %ax, %es
mov $msg, %si # load msg
mov $0xE, %ah # interrupt service
xor %bx, %bx # page num -- don't care
jmp putstring
putstring:
.loop:
lodsb # load at %ds:(%si)
test %al, %al
jz .done
int $0x10
jmp .loop
.done:
cli
hlt
msg: .asciz "You shall not see this message on real hardware."
.space 510 - (. - _start)
.word 0xaa55
I've sorted out many possibilities with some tests and it appears there may be something wrong with the addressing, despite I set up DS, because writing the same character constant in a loop works flawlessly. Furthermore, the issue also endures when writing to 0xB800.
I compile and link with:
Code: Select all
as test.S -o lol.o && ld --oformat binary -o main.img -Ttext 0x7C00 lol.o
----------------------
I managed to solve by writing to the VGA display directly rather than relying on the untrustworthy INT 0x10 that seems to cause some BIOSs to overwrite regions of the MBR, as turned out from intx13's significant job. More details here onward.