阅读bootsector redux

时间:2013-07-17 22:29:51

标签: assembly x86 nasm boot

好的,轮到我问一个问题了。 “我的代码出了什么问题?”它是一个dos .com文件(x86),用Nasm编写,并在引导下运行到FreeDos(不是DosBox)。

; 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

; 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)中逐步执行此操作时,我得到预期的输出(或多或少),但不是“程序正常终止”,而是“意外的单步断点”(或类似) ,表示我“在树林里”。当我尝试“以速度”运行时,它会挂起机器而根本没有输出!这些天Dos很快就开始了,但是过了一段时间它仍然会变老。我认为现在是时候另外看一眼了!

我意识到我已经完成了一些“文档记录不足”的事情 - 例如ipaam 16 - 但这些事情“曾经对我有用”......而且似乎在调试器。我在做什么让机器挂起(根本没有输出)?

阿米特,如果你这么倾向,请告诉我这在DosBox中的作用。其他任何人,谢谢你的帮助!

编辑:好的......我“修复”了它。我不知道怎么样!通过“完全无意义的中断”,它可以工作。没有它,与之前相同的结果 - 挂起没有输出。显然,FreeDos不喜欢int 29h作为第一个中断(?)。不知道为什么。我记得以前从未见过这样的事情。这个版本有一个稍微好一点的hexdump - 包括ascii,这可以让你更容易判断你是否正在查看真正的bootsector。我有一个想法,它不会在DosBox中工作......这使整个练习变得毫无意义......

int 13h

; 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-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 ;--------------------

......现在已经够了......

2 个答案:

答案 0 :(得分: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 | ....úúG@ö?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.öF.@u
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Áê.@á?÷á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 | .$.'.ð.@`»..´.Í.
61 C3 00 00 00 00 44 63 40 F6 3F 30 73 20 80 01 | aÃ....Dc@ö?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ª

答案 1 :(得分:0)

enter image description here

查找在dosbox环境中运行的代码的附加输出。我想在这里提出一个有趣的观点,当我将int29h替换为int 10h / ah = 0x0e时,输出不同,十六进制值已经改变。

enter image description here