2011-07-11 66 views
5

**請注意,當我說啓動程序時,我並不是指啓動操作系統的程序。我的意思是,一個簡單的程序在您啓動計算機並執行某些操作時運行。簡單的NASM「引導程序」無法正確訪問內存?

好的,所以我不是極其精通Assembly/NASM,但我認爲我有足夠的把握來編寫簡單的啓動程序。

那麼,我想到我有足夠的把握。顯然不是。

我試過一個簡單的啓動程序,我在網上找到。它運行良好(打印字母'A')。然後我修改它以打印存儲在內存中的一封信。它失敗了;而不是打印'A',它會打印笑臉。 (我發誓,電腦在嘲笑我現在。)

這是從源文件中的代碼:

[BITS 16] ; We start up in 16-bit real mode 
[ORG 0x7C00] ; We're booted into memory at this address. (Or so I'm told) 

mov ah, 0x0E  ; Teletype command 
mov bh, 0x00  ; Page number 
mov bl, 0x07  ; Attributes (7 == white foreground, black background) 
mov al, [testChar] ; Character to print; load it from the memory referenced by testChar. 

int 0x10 ; Tell the BIOS to execute the teletype command. 

jmp $ ; Infinite loop prevents us from going off and executing the other junk in memory 

testChar db 65 ; This is the character we want to print. 'A'. 

; The following code pads the rest of the outputted binary file 
; and concludes it with the bootloader signature so I don't have 
; to do so manually. 
times 510-($-$$) db 0 
dw 0xAA55 

如果我取代「移動人,[testChar]」與「舉動al,65',字母'A'打印正確。我嘗試過移動內存聲明,我已經嘗試了括號或括號中的每個組合括號或者ORG,並且我嘗試了遞增和遞減testChar(即[testChar + 1])。每一次,它都會打印一個笑臉,一個反面的笑臉(當我遞增testChar時),或者什麼都不打(當我把內存聲明放在代碼之前,可能是因爲沒有執行代碼= P)。我不能讓這該死的東西去工作。

現在,對於規範(因爲他們很可能相關的):

  • 我運行一個戴爾Latitude CPi的配備了Intel Pentium II處理器,因爲這是我的一切來測試(我不用我的普通電腦測試彙編程序,地獄號)。我很確定所說的處理器是x86,因爲我已經運行了Windows XP,Ubuntu和Arch Linux。

  • 我目前正在使用NASM編寫和編譯Arch Linux上的程序。

  • 引導程序是從軟盤

  • 我用 'NASM -f斌FILENAME' 編譯代碼運行。

  • 我然後從「mtools的」包使用「mformat」命令用於AL經由編譯引導程序轉移到軟盤「mformat -f 1440 -B BOOTPROGRAM答:」。

那麼,這次我搞砸了什麼?或者是我的處理器/ BIOS有問題?

+0

笑臉可能意味着它正在打印ascii字符1,這意味着您沒有正確使用'[testChar]'。我在我的ASM上生鏽得太過分了,因爲我記得如何正確地做到這一點...... –

+0

我以爲這可能就是它。問題是,我沒有看到任何其他方式來做到這一點。 NASM手冊說如果我想從一個地址獲取內存(這是testChar的實際內容),我必須將其放在括號內。當我查看實際的二進制文件時,相對於程序的開始,testChar應該是0x0e。所以,如果我輸入'testChar',它會把0x0e放入AL寄存器。但是如果我輸入'[testChar]',它應該把地址0x0e中存儲的值。但是,相反,它似乎更喜歡放置一個1(或無論是笑臉的ASCII密鑰),而不是進入內存。 – AnonymousJohn

+1

「啓動程序」的術語是bootloader。 –

回答

3

DS可能是充滿了一些垃圾值,所以只是做:

push cs 
pop ds 

mov ax, cs 
mov ds, ax 
mov es, ax 

更重要的是,不要相信CS和做:

xor ax, ax 
mov ds, ax 

請參閱this discussion:某些BIOS可能使用07c0:0000而不是傳統的0000:7c00,特別是從CD-ROM啓動時使用ElTorito。

+0

我試過這兩個版本。當我現在啓動它時,屏幕上什麼都不顯示。不是開玩笑。 – AnonymousJohn

+0

那麼,也就是說,當我在執行其他任何操作之前使用插入的任何一段代碼啓動它時,它什麼都不顯示。人力資源管理。我即將嘗試將65添加到AL寄存器。如果笑臉的ASCII碼實際上是1,那麼它應該顯示B. – AnonymousJohn

+0

添加65到AL寄存器加載testChar使後屏幕變爲空白也是如此。我不知道還有什麼要做。 – AnonymousJohn

0

這是產生以下代碼(只需在編譯的代碼上運行objdump)。

00000000 B40E    mov ah,0xe 
00000002 B700    mov bh,0x0 
00000004 B307    mov bl,0x7 
00000006 A00D7C   mov al,[0x7c0d] 
00000009 CD10    int 0x10 
0000000B EBFE    jmp short 0xb 
0000000D 41    inc cx ; this is actually your testChar 
            ; ignore the opcode translation 

現在如果你位於0x7C00,然後[0x7c0d]將在該最後一個字節(即0×41或65,或ASCII 「A」)。但如果像其他貢獻者之一(ninjalj)提到你有一些奇怪的BIOS錯誤,這意味着你不是位於0x7C00然後[0x7c0d]是任何人的猜測。

0

當我第一次運行它時,它運行良好!它打印'A'。使用命令nasm [filename.asm] -o [filename.com] -l [filename.lst]

我使用了nasm OSbad.asm -o OSbad.com。使用MagicISO製作可啓動映像文件OSbad.iso並使用Windows磁盤刻錄機將其刻錄到DVD/RW。裝載了Oracle VM,並製作了一臺256 MB RAM,CD/DVD,2GB硬盤的新虛擬機。用DVD引導,並在屏幕上打印「A」。

所以我想你的程序工作。它必須是你正在做的其他事情,這使得它無法工作。

+0

也適用於QEMU 。 –

相關問題