好的,輪到我問一個問題。 「我的代碼有什麼問題?」這是一個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 16
和int 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
;--------------------
...這就是夠了......
_「告訴我這是什麼在DosBox」_:它打印一個屏幕00。 – Michael
@Frank我現在無法訪問我的DosBox,只要有了它,就會讓你知道。 –
@Frank剛剛發現這個鏈接,它使用aam16在十六進制打印,但不知道它是否對你有任何用處.http://www.programmersheaven.com/mb/x86_asm/206762/206762/aam-16-discovered-4 -hex-prints /?S = 900000 –