Issue
Now I am programming my operating system in assembly and I tried to load it into flash drive. But when I try to start the operating system, it shows me strange characters.
The assembly code: https://github.com/Zahon7/ZahonOS/blob/main/ZahonOS.asm
[org 0x7c00]
call newline
call newline
call newline
call newline
call newline
call newline
call newline
call newline
call newline
call newline
call newline
call newline
mov bx, bm1
call printf
mov bx, bm2
call printf
call cls
mov bh, 70h
call color
mov bx, welmsg
call printf
wywtd:
mov bx, welmsg2
call printf
call waitforkey
cmp al, 49
je reboot
cmp al, 50
je guess
mov bx, invalidmsg
call printf
call waitforkey
call cls
mov bh, 70h
call color
call wywtd
jmp $
good:
mov bx, okans
call printf
call waitforkey
call reboot
guess:
call cls
mov bh, 70h
call color
mov bx, gmsg
call printf
call waitforkey
cmp al, 49
je good
mov bx, wrongans
call printf
call waitforkey
call reboot
reboot:
db 0x0ea
dw 0x0000
dw 0xffff
newline:
mov bx, nl
call printf
ret
color:
mov ah, 06h
xor al, al
xor cx, cx
mov dx, 184FH
; mov bh, 1Fh
int 10h
ret
waitforkey:
mov ah, 00h
int 16h
ret
cls:
pusha
mov ah, 0x00
mov al, 0x03
int 0x10
popa
ret
printf:
mov ah, 0x0e
.Loop:
cmp [bx], byte 0
je .Exit
mov al, [bx]
int 0x10
inc bx
jmp .Loop
.Exit:
ret
okans: db "Correct answer!", 0x00
wrongans: db "Wrong answer!", 0x00
gmsg: db "What is 78 * 23?", 0x0a, 0x0d, "[1] 1794", 0x0a, 0x0d, "[2] 1894", 0x0a, 0x0d, "[3] 1872", 0x0a, 0x0d, 0x00
invalidmsg: db "Invalid option!", 0x0a, 0x0d, 0x00
nl: db 0x0a, 0x0d, 0x00
welmsg: db "Welcome to ZahonOS Light edition!", 0x0a, 0x0d, 0x00
welmsg2: db "what do you want to do?", 0x0a, 0x0d, "[1] Restart", 0x0a, 0x0d, "[2] Game", 0x0a, 0x0d, 0x0a, 0x0d, "Answer: ", 0x00
bm1: db "Booting ZahonOS Light edition...", 0x0a, 0x0d, 0x00
bm2: db "Done!", 0x00
times 510-($-$$) db 0
dw 0xaa55
Also this is my first question on stack overflow.
Solution
When a bootsector program begins, the segment registers cannot be trusted to contain any particular value. In accordance with your [org 0x7c00]
and the instructions that you further use to address memory, the DS
segment register needs to contain 0. You must set it up yourself:
xor ax, ax
mov ds, ax
mov es, ax
Similarly, your program accesses the stack a lot but you don't make sure that the pre-existing stack is up to that task. You must set it up yourself:
xor ax, ax
mov ss, ax
mov sp, 0x7C00 ; Right below the bootsector
The BIOS.Teletype function 0Eh already uses the BL
and BH
registers (together they form BX
) as some of its parameters. Therefore it would be better to use the SI
register as the pointer that you provide to your printf.
At the conclusion of processing an invalid answer you use call wywtd
to repeat all over again. It makes more sense to not call but rather jump in this instance:
jmp wywtd
I don't know if this is on purpose, but the bm1 and bm2 messages are immediately erased by you clearing the screen...
call reboot reboot:
This call reboot
is redundant. The execution can just as well fall through into reboot:.
newline: mov SI, nl call printf ret
You could replace this so-called tail call by a jump jmp printf
.
But the most efficient would be to put the newline code directly above the printf code. That would shave off even the jmp printf
:
newline:
mov SI, nl
printf:
...
[org 0x7c00]
xor ax, ax
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0x7C00
call newline
call newline
call newline
call newline
call newline
call newline
call newline
call newline
call newline
call newline
call newline
call newline
mov SI, bm1
call printf
mov SI, bm2
call printf
call cls
mov bh, 70h
call color
mov SI, welmsg
call printf
wywtd:
mov SI, welmsg2
call printf
call waitforkey
cmp al, 49
je reboot
cmp al, 50
je guess
mov SI, invalidmsg
call printf
call waitforkey
call cls
mov bh, 70h
call color
JMP wywtd
jmp $
good:
mov SI, okans
call printf
call waitforkey
call reboot
guess:
call cls
mov bh, 70h
call color
mov SI, gmsg
call printf
call waitforkey
cmp al, 49
je good
mov SI, wrongans
call printf
call waitforkey
reboot:
db 0x0ea
dw 0x0000
dw 0xffff
color:
mov ah, 06h
xor al, al
xor cx, cx
mov dx, 184FH
; mov bh, 1Fh
int 10h
ret
waitforkey:
mov ah, 00h
int 16h
ret
cls:
pusha
mov ah, 0x00
mov al, 0x03
int 0x10
popa
ret
newline:
mov SI, nl
printf:
mov ah, 0x0e
mov bx, 000Fh ; DisplayPage BH=0, GraphicsColor BL=15 (BrightWhiteOnBlack)
.Loop:
mov al, [SI]
test al, al
jz .Exit
int 0x10
inc SI
jmp .Loop
.Exit:
ret
okans: db "Correct answer!", 0x00
wrongans: db "Wrong answer!", 0x00
gmsg: db "What is 78 * 23?", 0x0a, 0x0d, "[1] 1794", 0x0a, 0x0d, "[2] 1894", 0x0a, 0x0d, "[3] 1872", 0x0a, 0x0d, 0x00
invalidmsg: db "Invalid option!", 0x0a, 0x0d, 0x00
nl: db 0x0a, 0x0d, 0x00
welmsg: db "Welcome to ZahonOS Light edition!", 0x0a, 0x0d, 0x00
welmsg2: db "what do you want to do?", 0x0a, 0x0d, "[1] Restart", 0x0a, 0x0d, "[2] Game", 0x0a, 0x0d, 0x0a, 0x0d, "Answer: ", 0x00
bm1: db "Booting ZahonOS Light edition...", 0x0a, 0x0d, 0x00
bm2: db "Done!", 0x00
times 510-($-$$) db 0
dw 0xaa55
Answered By - Sep Roland
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.