Reputation: 57
I am developing a simple bare-metal OS, and my function for printing strings works only on some strings (eg "Hello World") but not others (eg "Press F1 for help")
[ORG 0x7C00]
msg db "Press F1 for help",0
main:
mov AH, 00h
int 16h
cmp AH, 0x3B
je help
jmp main
help:
mov si, msg
call print
jmp main
; Print library, invoke with "call print" example:
; msg db "Foobar",0
; mov SI, msg
; call print
%include "printlib.inc"
return:
ret
times 510-($-$$) db 0;
db 0x55
db 0xAA
printlib.inc:
print:
mov ax, 0x07c0
mov ds, ax
cld
jmp .loop
.loop:lodsb
or al, al ; zero=end or str
jz .retn ; get out
mov ah, 0x0E
mov bh, 0
int 0x10
jmp .loop
.retn:
ret
Upvotes: 1
Views: 118
Reputation: 58805
The BIOS will always start execution at the first byte of the boot sector, and in your case that appears to be the string, so you're executing data. (The fact that you put in a label called main
doesn't affect this; nothing looks at it.) It could be that your "Hello world" string just happens to correspond to instructions that don't totally break everything.
Try moving the string to be after all the code, or else insert a jmp main
before it.
Also, you have an inconsistency between your ORG
directive and your ds
segment. Your boot sector gets loaded at linear address 0x7c00
. You can think of this in segment:offset form as 0000:7c00
or 07c0:0000
(or other ways in between if you really want). So to access data in the boot sector, you either need to load ds
with zero and use [ORG 0x7c00]
, or else load ds
with 0x07c0
and use [ORG 0]
. However, your code mixes the two.
Upvotes: 2