2013-07-17 87 views
2

好的,輪到我問一個問題。 「我的代碼有什麼問題?」這是一個dos.com文件(x86),用Nasm編寫,並在啓動FreeDos(而不是DosBox)的情況下運行。閱讀bootsector還原

; nasm -f bin -o readmbr.com readmbr.asm 

org 100h ; offset where dos will load us 

section .text 

mov si, 5 ; retry count 
read: 
mov dx, 80h ; drive 
mov cx, 1 ; segment 
mov bx, buffer 
mov ax, 201h ; read 1 sector 
int 13h 
jnc goodread 

mov ah, 0 ; reset drive 
int 13h 
dec si 
jnz read 
jmp exit 

goodread: 
mov si, buffer 
mov cx, 512 
top: 
lodsb 
aam 16 
xchg al, ah 
call printhex 
xchg al, ah 
call printhex 
mov al, ' ' 
int 29h 
loop top 

exit: 
int 20h 
;mov ah, 4Ch 
;int 21h 
; ret 
printhex: 
cmp al, 9 
jbe not_alpha 
add al, 7 
not_alpha: 
add al, '0' 
int 29h ; print the character in al 
ret 

section .bss 
buffer resb 512 

當我通過這在調試器(FREEDOS' DEBUG),我得到預期的輸出步驟(更多或更少),但不是‘程序正常終止’,我得到「意外單步斷點「(或類似),而ip表示我」在樹林裏「。當我試圖以「速度」運行它時,它將機器完全掛起而沒有輸出!這些日子,Dos很快就會啓動,但它在一段時間後仍會變老。我認爲是時候將其他的眼光放在這個上面了!

我意識到我已經完成了一些「較少文檔記錄」的東西 - 例如aam 16int 29h - 但這些東西「用於工作」對我來說似乎在調試器中起作用。我在做什麼使機器掛起(根本沒有輸出)?

艾米特,如果你這麼傾向,告訴我這是什麼在DosBox。其他人,感謝您的幫助!

編輯:好吧......我「固定」它。我不知道如何!隨着「完全無意義的中斷」,它的工作。沒有它,與以前相同的結果 - 掛起而沒有輸出。顯然,FreeDos不喜歡int 13h作爲第一個中斷(?)。不知道爲什麼。我不記得曾經見過這樣的事情。這個版本有一個更好的hexdump - 也包含ascii,這會讓你更容易知道你是否在看真實的啓動扇區。我有一個想法,它不會在DOSBox中工作......這使得整個運動,而毫無意義......

; nasm f-bin -o readmbr.com readmbr.asm 

org 100h 

section .bss 
    buffer resb 512 

section .text 

; completely meaningless interrupt! 
    mov dl, 13 
    mov ah, 2 
    int 21h 

    mov dx, 80h ; drive 
    mov cx, 1 ; sector (not "segment", idiot) 
    mov bx, buffer 
    mov ax, 201h ; read one sector 
    int 13h 
    jc exit 

; dump 512 bytes as hex, and ascii (if printable), 16 at a time 
    mov si, buffer 
    mov di, 32 ; loop counter 
dumpem: 
    call dump16 
    dec di 
    jnz dumpem 

exit: 
    ret 
;------------------ 

;-------------------- 
; print character in al to stdout 
; returns: nothing useful 
printchar: 
    push ax 
    push dx 
    mov dl, al 
    mov ah, 2 
    int 21h 
    pop dx 
    pop ax 
    ret 
;------------------ 

;-------------------- 
dump16: 
; prints 16 bytes pointed to by si, as hex and as ascii (if printable) 
; returns: si pointed to next byte. ax, cx trashed. 

    mov cx, 16 
    push si ; save it for the ascii part 
top: 
    lodsb ; al <- [si], inc si 
    aam 16 ; split al into ah and al - four bits per 
    xchg al, ah ; we want the high one first 
    cmp al, 9 
    jbe not_alpha 
    add al, 7 ; bump 10 - 15 up to 'A' - 'F' 
not_alpha: 
    add al, '0' 
    call printchar 
    xchg al, ah ; swap 'em back and print low nibble 
    cmp al, 9 
    jbe not_alpha2 
    add al, 7 
not_alpha2: 
    add al, '0' 
    call printchar 
    mov al, ' ' 
    call printchar 
    loop top 

    mov al, '|' 
    call printchar 
    mov al, ' ' 
    call printchar 

    pop si ; get back pointer to 16 bytes 
    mov cx, 16 
asciitop: 
    lodsb 
    cmp al, 20h ; we don't want to print control characters! 
    jae printable 
    mov al, '.' 
printable: 
    call printchar 
    loop asciitop 
; and throw a CR/LF 
    mov al, 13 
    call printchar 
    mov al, 10 
    call printchar 
    ret 
;-------------------- 

希望Linux版本,而我們在這?爲什麼不?可能更爲有用...

; nasm -f elf32 myprog.asm 
; ld -o myprog myprog.o -melf_i386 
; 
; since only root is going to have access to the MBR, 
; run it as root... or if you wish a user to be able to run it... 
; as root: 
; chown root:root myprog 
; chmod +s myprog 

global _start 

section .data 

; on my valuable antique system, this is the first hard drive 
; (not necessarily the one I booted from) 
; on a more modern system, probably "sda" or so...? 

    filename db "/dev/hda", 0 

section .bss 
    buffer resb 512 
    file_desc resd 1 

section .text 
_start: 
    nop 

; open the file 
    ; don't care about edx, since we're not creating the file 
    mov ecx, 0 ; readonly 
    mov ebx, filename 
    mov eax, 5 ; sys_open 
    int 80h 

    test eax, eax ; fancy error handler :) 
    js exit 
    mov [file_desc], eax 

; read all 512 bytes 
    mov edx, 512 
    mov ecx, buffer 
    mov ebx, [file_desc] 
    mov eax, 3 ; sys_read 
    int 80h 
    test eax, eax 
    js exit 

; dump 512 bytes as hex, and ascii (if printable), 16 at a time 
    mov esi, buffer 
    mov edi, 32 
dumpem: 
    call dump16 
    dec edi 
    jnz dumpem 

; the exit would close the file, but we'll be nice and close it 
    mov ebx, [file_desc] 
    mov eax, 6 ; sys_close 
    int 80h 
    test eax, eax 
    js exit 

; if we get here, pretend there was no error 

    xor eax, eax 

exit: 

; if there was an error, return it as an exit-code, 
; negated for easy readability. 
; view it with "echo $?". 

    mov ebx, eax 
    neg ebx 
    mov eax, 1 ; sys_exit 
    int 80h 
;------------------ 

;-------------------- 
; print character in al to stdout 
; returns: nothing useful 
printchar: 
    push edx ; save these, by preference 
    push ecx 
    push ebx ; C would expect ebx to be preserved 
    push eax ; has to be last - it serves as our buffer 

    mov ecx, esp ; buffer's on the stack 
    mov edx, 1 ; one only please 
    mov ebx, 1 ; stdout 
    mov eax, 4 ; sys_write 
    int 80h 

    pop eax 
    pop ebx 
    pop ecx 
    pop edx 
    ret 
;------------------ 

;-------------------- 
dump16: 
; prints 16 bytes pointed to by esi, as hex and as ascii (if printable) 
; returns: esi pointed to next byte. eax, ecx trashed. 

    mov ecx, 16 
    push esi ; save it for the ascii part 
top: 
    lodsb ; al <- [esi], inc esi 
    aam 16 ; split al into ah and al - four bits per 
    xchg al, ah ; we want the high one first 
    cmp al, 9 
    jbe not_alpha 
    add al, 7 ; bump 10 - 15 up to 'A' - 'F' 
not_alpha: 
    add al, '0' 
    call printchar 
    xchg al, ah ; swap 'em back and print low nibble 
    cmp al, 9 
    jbe not_alpha2 
    add al, 7 
not_alpha2: 
    add al, '0' 
    call printchar 
    mov al, ' ' 
    call printchar 
    loop top 

    mov al, '|' 
    call printchar 
    mov al, ' ' 
    call printchar 

    pop esi ; get back pointer to 16 bytes 
    mov ecx, 16 
asciitop: 
    lodsb 
    cmp al, 20h ; we don't want to print control characters! 
    jae printable 
    mov al, '.' 
printable: 
    call printchar 
    loop asciitop 
; and throw a linefeed... 
    mov al, 10 
    call printchar 
    ret 
;-------------------- 

...這就是夠了......

+0

_「告訴我這是什麼在DosBox」_:它打印一個屏幕00。 – Michael

+0

@Frank我現在無法訪問我的DosBox,只要有了它,就會讓你知道。 –

+0

@Frank剛剛發現這個鏈接,它使用aam16在十六進制打印,但不知道它是否對你有任何用處.http://www.programmersheaven.com/mb/x86_asm/206762/206762/aam-16-discovered-4 -hex-prints /?S = 900000 –

回答

0

enter image description here

找到你的代碼運行在DOSBox中的環境中連接輸出。我想在這裏提出一個有趣的問題,當我將int29h替換爲int 10h/ah = 0x0e時,輸出不同,十六進制值已更改。

enter image description here

+0

就像一個白癡,我忽略了把「集會」放在我的「標籤」中。謝謝你解決,誰做的。我是新來的,我能說什麼?既不是所有的零,也不是你發佈的屏幕截圖看起來像一個啓動器。虛擬的「DosBox」可能看不到「真正的」硬盤。 (如果您可以寫入真正的硬盤,嚴重的安全違規行爲!)我會重新啓動FreeDos並再次嘗試,而不是試圖這次「聰明」。 :)我更容易編寫一個Linux程序 - 完全不同的方法。我會盡快給您回覆。感謝所有迄今爲止的反饋! –

+0

@FrankKotler是否有可能在這裏附上你的MBR的O/P –

1

好。這是Linux版本的輸出(比重新啓動更容易)。它可怕地「包裹」,但你可以看到它是「LILO」。

FA EB 21 01 B2 01 4C 49 4C 4F 16 07 80 60 FC 47 | úë!.².LILO..`üG 
00 00 00 00 FA 9A FA 47 40 F6 3F 30 81 00 80 60 | ....úú[email protected]ö?0.` 
16 2B F3 01 B8 C0 07 8E D0 BC 00 08 FB 52 53 06 | .+ó.¸À.м..ûRS. 
56 FC 8E D8 31 ED 60 B8 00 12 B3 36 CD 10 61 B0 | VüØ1í`¸..³6Í.a° 
0D E8 64 01 B0 0A E8 5F 01 B0 4C E8 5A 01 60 1E | .èd.°.è_.°LèZ.`. 
07 80 FA FE 75 02 88 F2 BB 00 02 8A 76 1E 89 D0 | .úþu.ò»..v.Ð 
80 E4 80 30 E0 78 0A 3C 10 73 06 F6 46 1C 40 75 | ä0àx.<.s.ö[email protected] 
2E 88 F2 66 8B 76 18 66 09 F6 74 23 52 B4 08 B2 | .òfv.f.öt#R´.² 
80 53 CD 13 5B 72 57 0F B6 CA BA 7F 00 42 66 31 | SÍ.[rW.¶Êº.Bf1 
C0 40 E8 60 00 66 3B B7 B8 01 74 03 E2 EF 5A 53 | À@è`.f;·¸.t.âïZS 
8A 76 1F BE 20 00 E8 DD 00 B4 99 66 81 7F FC 4C | v.¾ .èÝ.´füL 
49 4C 4F 75 29 5E 68 80 08 07 31 DB E8 C7 00 75 | ILOu)^h..1ÛèÇ.u 
FB BE 06 00 89 F7 B9 0A 00 B4 9A F3 A6 75 0F B0 | û¾..÷¹..´ó¦u.° 
02 AE 75 0A 06 55 B0 49 E8 CD 00 CB B4 40 B0 20 | .®u..U°IèÍ.Ë´@° 
E8 C5 00 E8 B2 00 FE 4E 00 74 07 BC E8 07 61 E9 | èÅ.è².þN.t.¼è.aé 
5C FF F4 EB FD 60 55 55 66 50 06 53 6A 01 6A 10 | \ÿôëý`UUfP.Sj.j. 
89 E6 53 F6 C6 60 74 6E F6 C6 20 74 14 BB AA 55 | æSöÆ`tnöÆ t.»ªU 
B4 41 CD 13 72 0B 81 FB 55 AA 75 05 F6 C1 01 75 | ´AÍ.r.ûUªu.öÁ.u 
3F 52 06 B4 08 CD 13 07 72 B4 51 C0 E9 06 86 E9 | ?R.´.Í..r´QÀé.é 
89 CF 59 C1 EA 08 92 40 83 E1 3F F7 E1 93 8B 44 | ÏYÁê[email protected]á?÷áD 
08 8B 54 0A 39 DA 73 94 F7 F3 39 F8 77 8E C0 E4 | .T.9Ús÷ó9øwÀä 
06 86 E0 92 F6 F1 08 E2 89 D1 41 5A 88 C6 EB 1C | .àöñ.âÑAZÆë. 
B4 42 5B BD 05 00 60 CD 13 73 16 4D 74 BA 31 C0 | ´B[½..`Í.s.Mtº1À 
CD 13 61 4D EB F0 66 50 59 58 88 E6 B8 01 02 EB | Í.aMëðfPYXæ¸..ë 
E1 8D 64 10 61 C3 66 AD 66 09 C0 74 0A 66 03 46 | ád.aÃf­f.Àt.f.F 
10 E8 61 FF 80 C7 02 C3 C1 C0 04 E8 03 00 C1 C0 | .èaÿÇ.ÃÁÀ.è..ÁÀ 
04 24 0F 27 04 F0 14 40 60 BB 07 00 B4 0E CD 10 | .$.'.ð[email protected]`»..´.Í. 
61 C3 00 00 00 00 44 63 40 F6 3F 30 73 20 80 01 | aÃ[email protected]ö?0s . 
01 00 83 EF FF FF 3F 00 00 00 41 45 31 09 00 EF | ..ïÿÿ?...AE1..ï 
FF FF 82 EF FF FF 80 45 31 09 D0 87 20 00 00 00 | ÿÿïÿÿE1.Ð ... 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 AA | ..............Uª 
+0

謝謝Frank,看起來我在這裏運氣不好,因爲在運行Linux版本的代碼時只能看到黑色屏幕 –

+0

@AmitSinghTomar好吧, Linux版本,如果您在運行後立即鍵入'echo $?',應該輸出一個錯誤編號。 13是我得到的最常見的 - 權限被拒絕。意思是我忘了以root身份運行它,或者按照註釋中的描述「烹飪」文件。 2 - 沒有這樣的文件,6 - 沒有這樣的設備或地址,19 - 沒有這樣的設備。如果必須,請在errno.h中查看它們。如果它說0,我的代碼只是越野車。我認爲最簡單的方式來告訴你啓動的設備是輸入'df'並查看「/」上掛載的是什麼。勇氣! [email protected] –

+0

HI Frank我做了你的建議,echo $? ,其輸出結果爲2意味着沒有這樣的文件,並且在/「下安裝df顯示/ dev/loop0的輸出。我應該怎麼做,/ dev/loop0看起來不像是從硬盤啓動的還是呢? –