2013-08-31 43 views
2

我做了這段代碼,這應該是簡單的操作系統,應該打印出「Hello world!」。 x86彙編操作系統你好世界不按預期工作

bits 16 
    mov bx,msg 
    call printstr 
printstr: 
    mov al,byte[bx] 
    mov ah,0Eh 
    int 10h 
    inc bx 
    cmp byte[bx],0 
    je end 
    jmp printstr 
end: 
    jmp end 
msg: db "Hello world!",0 
times 510-($-$$) db 0 
dw 0xaa55 

我組裝了NASM。 當我在QEMU上運行它時,它會打印出一個奇怪的字符和'S'。

我用這些參數運行QEMU 「qemu-system-x86_64 ost.bin」其中「ost.bin」是該文件。 有人知道解決方案嗎?

+0

你也可能想跟蹤這個SO問題。他們看起來很相似:http:// stackoverflow。com/questions/18515203/first-os-i-cant-make-it-work – lurker

回答

1

有幾個問題在你的代碼:

bits 16 
mov bx, msg 

msg現在只包含抵消輸出二進制開始您的留言。您可以通過將0x7c00添加到msg或設置程序原點(在內存中啓動,ORG 0x7c00)來解決此問題。

call printstr 
printstr: 
    mov al,byte[bx] 

BX不是索引串起人物好寄存器,因爲它包含的顏色(低字節)和頁面(高字節)的信息。

mov ah,0Eh 
    int 10h 

您不必設置AH0x0E每次打印的字符。它可以在代碼的開始處完成。

inc bx 
    cmp byte[bx], 0 

在這種類型的循環中,您應該首先檢查值,然後對其進行處理。如果BX+0上的字符等於0,您會怎麼做?你會錯過這個事實,那會導致錯誤的輸出甚至無限循環。

je end 
    jmp printstr 

這肯定會導致無限循環,因爲您已經在該過程中。

end: 
    jmp end 

首選語法爲jmp $(其中美元符號的意思是 「在這裏」)。

msg: db "Hello world!",0 
times 510-($-$$) db 0 
dw 0xaa55 
2

您必須在代碼的開頭插入「org 7c00h」。

而且,您必須在打印後停止該程序,否則它將再次落入到printstr過程中。

也許是這樣的:

sleep: hlt 
     jmp sleep 
+0

謝謝,這工作正常。 – Smax

+0

@Smax投票的好答案,並接受它是否有效。 – user35443

+0

@ user35443我需要至少15個聲望才能投票。 – Smax

0

主要的問題似乎是段寄存器(DS和ES)未初始化。不需要「組織7C00h」;該程序也可能從地址100h(適用於DOS .COM文件)或0h開始。根據起始地址,段寄存器必須初始化爲7C0h(org 0h),7B0H(org 100h)或0(org 7C00h)。

最後的「jmp sleep」指令就足夠了; 「HLT」指令絕對不是必需的。

+0

使用org 7c00h工作良好。 – Smax

+1

@Martin Rosenau這將是一個有趣的DOS程序,正好是512字節寬,並在最後有bootloader簽名。 – user35443

+0

馬丁是對的! QEMU可能會將您的段寄存器初始化爲0,但您無法在引導區中指望它! –