2013-07-15 56 views
1

我有一段代碼運行在實模式和printf在屏幕上的消息,我使用DOSBox中0.7作爲我的執行環境。下面是代碼請告訴我不對這個實模式代碼

jmp 0x7c0:start 

start: 
mov ax, cs ; set up segments 
mov ds, ax 
mov es, ax 
mov al,03h 
mov ah,0 
int 10h 
welcome db "This is insane now" 
mov si, welcome 
call print_string 
print_string: 
lodsb  ; grab a byte from SI 

or al, al ; logical or AL by itself 
jz .done ; if the result is zero, get out 
mov ah, 0x0E 
int 0x10  ; otherwise, print out the character! 
jmp print_string 
.done: 
ret 

我能夠裝配該代碼罰款,但是當我運行它,它只是掛在那兒和消息,我可以在Linux終端看到

Illegal read from b0671921, CS:IP  7c0: 4468 

這是我如何組裝它

 nasm PRINT.ASM -o out.com 

我試圖尋找在谷歌這條消息,並發現它可能是與DOSBox中的一個問題。

任何人都可以讓我知道在這裏可以是問題?

+1

你想寫一個引導程序? COM文件被加載到地址0x100,所以你不能以這種方式運行bootloader。您必須創建一個虛擬軟盤驅動器或硬盤驅動器,並在第一個扇區中放置引導加載程序二進制文件。而且,你的歡迎字符串缺少NUL終結符,不應該放在代碼中間,因爲CPU不知道代碼和數據之間的區別。 – Michael

+1

如果你真的想創建一個.COM文件(而不是引導程序),你應該使用'[org 0x100]'並且在開始時刪除'jmp'(並且用你的字符串變量解決上述問題)。 – Michael

+0

謝謝Micheal,會試試看。 –

回答

1

執行與代碼的問題是字符串常量的地方。它必須放在永遠不會「執行」的地方,因爲它不是代碼。

的另一個問題是代碼是如何結束。引導記錄應該加載一些其他代碼(操作系統內核或更大的引導程序)並跳轉到它。或者至少(如果你只是想測試某些東西)只是無限循環。在你的情況下,該程序將落入print_string子例程,然後嘗試「無法返回」。

這裏是固定的版本:

 org 7c00h 

start: 
     mov  ax, cs ; set up segments 
     mov  ds, ax 
     mov  es, ax 

     mov  al, 03h 
     mov  ah, 0 
     int 10h 

     mov  si, welcome 
     call print_string 

.sleep: 
     jmp  .sleep 



print_string: 
     lodsb  ; grab a byte from SI 

     test al, al ; logical or AL by itself 
     jz  .done ; if the result is zero, get out 

     mov  ah, 0x0E 
     int 0x10  ; otherwise, print out the character! 
     jmp  print_string 
.done: 
     ret 


welcome db "This is insane now", 0 

爲什麼跳被刪除? BIOS從磁盤加載引導扇區後,將其放置在地址0000h:7c00h處。分別跳轉到$ 0000:$ 7c00以開始執行代碼。

只要(有可能)的inial代碼在偏移$ 0000編譯,第一跳只更改段7c0h和偏移,以提供該程序的正確執行到0000h。

但是,我們可以設置我們的計劃,7C00h處(組織7C00h處),並通過這種方式簡單地避免使用一個指令的由來。

+0

感謝@johnfound的回答,想問你一對夫妻的疑惑1)爲什麼jmp 0x7c0:start已經從代碼中刪除,儘管Micheal在上面解釋了它,但是也想聽到你的聲音2)。或者至少(如果你只是想測試某些東西)只是簡單地做出無限循環,你能否詳細地展開它,或者如果在你的答案中增加它的細節將會很好。 –

+0

@AmitSinghTomar現在答案是固定的。沒有測試過,但應該沒問題。 – johnfound

+0

再次感謝Johnfound,會測試它並讓你知道結果。 –

1

讓我們一步一步:

jmp 0x7c0:start ;jump to start 

start: 

    mov ax, cs  ; set up segments    
    mov ds, ax 
    mov es, ax 


    mov al,03h  ; Set up screen to 80 by 25 
    mov ah,0 
    int 10h 

字符串不是可執行代碼,所以把它放在以前start標籤和JMP後。 字符串必須以零字符結束!

welcome db "This is insane now"#0 

mov si, welcome  ;Print string 
call print_string 

缺少敲定代碼退出程序妥善所謂print_string將再次

print_string: 
    cld   ;Clear direction flag instruction is missing 
    lodsb   

    or al, al ; test if zero char 
    jz .done  ; exit if zero char 
    mov ah, 0x0E ; Write Char in Teletype Mode 
    mov bh, 0 ; Define 0 page if we have multiple pages 
    int 0x10  ; print character! 
    jmp print_string 
    .done: 
    ret 
+0

謝謝GJ。爲了迴應。只是想知道我是否以正確的方式組裝這些代碼? –

相關問題