2017-03-08 86 views
2

學習https://github.com/cfenollosa/os-tutorial/tree/master/05-bootsector-functions-strings,我一直在試圖編寫自己的引導扇區。NASM指令序列

我正在嘗試打印給定的字符串。

這些是我的兩個文件:

boot_main.asm

[org 0x7c00] 

mov bx, hello 
call print 
jmp $ 

hello db 'HI', 0 

%include "boot_print.asm" 

times 510 - ($ - $$) db 0 
dw 0xaa55 

boot_print.asm

print: 
    pusha 

start: 
    mov al, [bx] 
    cmp al, 0 
    je done 

    mov ah, 0x0e 
    int 0x10 

    add bx, 1 
    jmp start 

done: 
    popa 
    ret 

print_nl: 
    pusha 
    mov ah, 0x0e 
    mov al, 0x0a 
    int 0x10 
    mov al, 0x0d 
    int 0x10 

    jmp done 

現在這個完美的作品,並打印 「HI」 到屏幕上。但是,如果我將指令hello db 'HI', 0開始。即

boot_main.asm

[org 0x7c00] 

hello db 'HI', 0 

mov bx, hello 
call print 
jmp $ 

%include "boot_print.asm" 

times 510 - ($ - $$) db 0 
dw 0xaa55 

這不能在所有打印任何東西。我試圖理解兩者之間的區別。任何幫助?

回答

3

彙編程序根據您在源文件中的寫入位置將內容放入內存中。如果你把它放在開頭,在org指令之後,HI\0字符串將被放置在那裏,並且CPU將嘗試運行它,就好像它是代碼一樣(執行無意義的事情和可能的錯誤)。

在原來的代碼,而是字符串位於jmp $,在那裏它被安全地保存在未有史以來指令指針到達位置之後。

如果您修改代碼以使CPU迴避,你會看到字符串,它再次開始工作:

[org 0x7c00] 
    jmp real_start 
    hello db 'HI', 0 
real_start: 
    mov bx, hello 
    call print 
    jmp $ 
    %include "boot_print.asm" 
    times 510 - ($ - $$) db 0 
    dw 0xaa55 

再次,這是顯而易見的,如果你認爲db並沒有真正做什麼魔法關於字符串,它只是在輸出二進制文件的位置輸出任意字節。如果你將它們寫入執行路徑中,CPU將在它們上面運行,如果你告訴CPU跳過它們,它將避免它們。

+1

你的例子,與sidestep錦上添花,美麗,謝謝! :) –

+1

@KarthikNayak:很高興幫助!有趣的是,當生成與位置無關的代碼時,和/或當您的數據很小但不符合立即數,但仍然可以從中受益時,實際上將其用於「現實生活中」已經在使用它的寒冷中緩存。 –

+0

關閉主題,你能解釋你的個人資料中的笑話嗎? –