Reputation: 3
I'm trying to learn x86 assembly. I'm trying to make a toy OS. I tried printing out a character that was inputted but it failed. Is there something wrong in the input? Or in the output? I have set AH
to 0x0E and used int 0x10
but it still doesn't work. Why doesn't it work?
Note: I'm very new to assembly, so if I got something wrong in the text or in the code, please don't say how dumb I am.
char:
db 0
mov ah, 0
int 0x16
mov ah, 0x0e
mov al, [char]
int 0x10
jmp $
times 510-($-$$) db 0
dw 0xaa55
Upvotes: 1
Views: 878
Reputation: 3
its awesome that you are getting started with assembly, and it can be quite overwhelming, but anyway, I have prepared a super simple "Hello, World!" Boot loader that should help make more sense to you :p
boot.asm:
org 0x7C00 ; BIOS loads our program at this address
bits 16 ; We're working at 16-bit mode here
_start:
cli ; Disable all interrupts
mov si, msg ; SI now points to our message
mov ah, 0x0E ; Indicate to the BIOS we're going to print chars
.loop lodsb ; Loads SI into AL and increments SI [next char]
or al, al ; Checks if the end of the string
jz halt ; jump to halt if the end
int 0x10 ; Otherwise, call interrupt for printing characters
jmp .loop ; Next iteration of the loop
halt: hlt ; CPU command to halt the execution
msg: db "Hello, World!", 0 ; Our message that we want to print
;; Magic numbers
times 510-($-$$) db 0 ; Aligning 512 bytes to take up initial boot sector
dw 0xAA55 ; Magic multiboot number
I hope this helps you understand a bit more about assembly, and I hope it makes you want to learn more. :p
Upvotes: 0
Reputation: 39691
char: db 0 mov ah, 0
In assembly, you need to store the data out of the way of the executing code. In this bootloader, execution started at the top where you placed a data item. The CPU will try to interpret it as an instruction but it will fail (most of the time).
I tried printing out a character that was inputted
Once you receive the character as input, you still need to actually store it in the memory labeled char. If you don't, then the instruction mov al, [char]
won't have anything useful to fetch!
Please note that in a bootloader, you are responsible to setup the segment registers. Your code depends on a correct DS
segment register. Because you didn't use an ORG
directive, the correct value for DS
will be 0x07C0.
And the BIOS.Teletype function 0x0E has additional parameters in BH
and BL
. Don't ignore these.
mov ax, 0x07C0
mov ds, ax
mov ah, 0 ; BIOS.GetKeyboardKey
int 0x16 ; -> AL charactercode, AH scancode
mov [char], al
mov bx, 0x0007 ; BH is DisplayPage (0), BL is GraphicsColor (White)
mov ah, 0x0E ; BIOS.Teletype
mov al, [char]
int 0x10
jmp $
char: db 0
times 510-($-$$) db 0
dw 0xAA55
Upvotes: 4