2

では、私が質問する番です。「私のコードの何が問題なのですか?」これは、Nasm で記述された dos .com ファイル (x86) であり、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

デバッガー (FreeDos の DEBUG) でこれをステップ実行すると、予想される出力 (多かれ少なかれ) が得られますが、「プログラムが正常に終了した」のではなく、「予期しないシングルステップ ブレークポイント」(または同様のもの) が得られます。ipは、私が「森の外」にいることを示しています。「高速で」実行しようとすると、出力がまったくない状態でマシンがハングします。Dos は最近かなり速く起動しますが、しばらくするとまだ古くなります。これに別の目を向ける時が来たと思います!

「あまり文書化されていない」ことをいくつか行ったことに気づきました-aam 16たとえばint 29h-しかし、これらのことは「以前は機能していました」...そしてデバッガーで機能するようです。マシンがハングアップする (出力がまったくない) 原因は何ですか?

アミット、もしよろしければ、これが DosBox で何をするのか教えてください。他の誰でも、助けてくれてありがとう!

編集:わかりました...「修正」しました。方法がわからない!「まったく無意味な割り込み」で、動作します。それがなければ、前と同じ結果 - 出力なしでハングします。int 13hどうやら、FreeDos は最初の割り込み (?) として気に入らないようです。理由はわかりません。私はこれまでにこのようなものを見た記憶がありません。このバージョンには、わずかに優れた 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
;--------------------

...そして今はそれで十分です...

4

2 に答える 2

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ª
于 2013-07-21T12:37:56.647 に答える
0

ここに画像の説明を入力

dosbox 環境で実行したコードの添付出力を見つけます。ここで取り上げたい興味深い点の 1 つは、int29h を int 10h/ah=0x0e に置き換えると、出力が異なり、16 進値が変更されたことです。

ここに画像の説明を入力

于 2013-07-18T17:59:17.433 に答える