這是我的 ASM 代碼:
bits 16
org 0x7c00
boot:
mov bx, string
call print_string
hlt
string:
db 'Booting OS', 0
printloop:
; Move the character into al so the BIOS interrupt prints it
mov al, [bx]
int 0x10
; Increment bx by 1 so it goes to the next character of the string
add bx, 1
; Check if the value is 0, if so, exit out of the loop, if it's not 0, continue looping
mov cx, [bx]
cmp cx, 0x0000
jne printloop
jmp print_fin
print_string:
pusha
mov ah, 0x0e
jmp printloop
print_fin:
popa
ret
; Mark the device as bootable
times 510-($-$$) db 0 ; Add any additional zeroes to make 510 bytes in total
dw 0xAA55 ; Write the final 2 bytes as the magic number 0x55aa
這是代碼的輸出:
啟動作業系統 ?í????ù uò?`?ía??
我很確定這不是我輸入的內容。
我不知道為什么它會超過終結者..
編輯:我只是嘗試將字串末尾的位元組設定為 ,以防0x0000萬一它與 有所不同0,它仍然剛好經過終止符。
uj5u.com熱心網友回復:
如果您將字串寫在TIMES指令的正上方(因此位于其余代碼的下方),那么這是那些不會被注意到的錯誤之一。第一個填充零就可以了。
...
string:
db 'Booting OS', 0
times 510-($-$$) db 0
dw 0xAA55
編輯:我只是嘗試將字串末尾的位元組設定為 ,以防
0x0000萬一它與 0 有所不同,但它仍然經過了終止符。
如果對什么0x0000意思沒有誤解,您的編輯本可以解決問題。您撰寫數字常量的方式不會對DB指令強加任何大小資訊。
db 'Booting OS', 0
db 'Booting OS', 0x00
db 'Booting OS', 0x0000
db 'Booting OS', 0x00000000
以上所有編碼都相同,在文本后附加一個零位元組。
您使用 0x0000 解決它的努力將通過DW指令起作用,在文本中附加一個零字:
db 'Booting OS'
dw 0x0000
但即使在這里,您也可以通過多種方式撰寫終止符:
dw 0
dw 0x00
dw 0x0000
dw 0x00000000
與邊界問題無關,但print_string代碼太復雜了。更好地使用這樣的代碼:
mov si, string
call print_string ; -> SI (AX)
...
; IN (si) OUT (si) MOD (ax)
print_string:
push bx
mov bx, 0x00007 ; BH is DisplayPage, BL is GraphicsColor
jmp .begin
.loop:
mov ah, 0x0E ; BIOS.Teletype
int 0x10
.begin:
mov al, [si] ; \ Alternatively, you can use LODSB here
inc si ; /
cmp al, 0
jne .loop
pop bx
ret
uj5u.com熱心網友回復:
我已經修復了它,問題是我使用 16 位暫存器來比較 8 位暫存器(cx而不是cl),并且cmp正在比較錯誤的值。(如果我做錯了,請告訴我我做錯了什么。我才剛剛開始學習 ASM)
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/315393.html
上一篇:跳轉指令的距離對延遲的影響
