我正在努力学习x86汇编。我想做一个玩具操作系统。我试着打印输入的字符,但是失败了。输入有什么问题吗?或者在输出中?我已经将AH
设置为0x0E并使用int 0x10
,但它仍然不起作用。为什么它不起作用?
注意:我是汇编的新手,所以如果我在文本或代码中有什么错误,请不要说我有多笨。
char:
db 0
mov ah, 0
int 0x16
mov ah, 0x0e
mov al, [char]
int 0x10
jmp $
times 510-($-$$) db 0
dw 0xaa55
char: db 0 mov ah, 0
在汇编中,您需要将数据存储在执行代码的路径之外。在这个引导加载程序中,执行从放置数据项的顶部开始。CPU将尝试将其解释为指令,但它将失败(大多数情况下)。
我尝试打印输入的字符
接收到字符作为输入后,仍然需要将其实际存储在标记为char的内存中。如果你不这样做,那么指令mov al, [char]
将没有任何有用的东西可以获取!
请注意,在引导加载程序中,您负责设置段寄存器。您的代码取决于正确的DS
段寄存器。因为您没有使用ORG
指令,所以DS
的正确值将是0x07C0。
和BIOS。电传输入函数0x0E在BH
和BL
中有额外的参数。不要忽略这些
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
你开始使用汇编真是太棒了,它可能是相当压倒性的,但无论如何,我准备了一个超级简单的&;Hello, World!&;引导加载程序,应该帮助你更有意义: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
我希望这能帮助你更多地理解汇编,我希望它能让你想要学习更多。: p