Assembly 读取引导扇区redux

Assembly 读取引导扇区redux,assembly,x86,nasm,boot,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 b

好的,轮到我提问了。“我的代码怎么了?”它是一个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

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

当我在调试器(FreeDos’DEBUG)中单步执行此操作时,我得到的是预期的输出(或多或少),但不是“程序正常终止”,而是“意外的单步断点”(或类似的断点),
ip
表示我“陷入了困境”。当我试图以“高速”运行它时,它会挂起机器,根本没有输出!Dos的靴子现在很快就穿上了,但过了一段时间它还是会变老。我想是时候让其他人看看了

我意识到我做了一些“不太好记录”的事情-
aam16
int29h
例如-但是这些事情“过去对我来说很有用”。。。并且似乎在调试器中工作。我在做什么使机器挂起(根本没有输出)

埃米特,如果你这么想的话,告诉我这在DosBox里有什么作用。其他人,谢谢你的帮助

编辑:好的。。。我“修复”了它。我不知道怎么做!使用“完全无意义的中断”,它可以工作。没有它,结果和以前一样-挂起而没有输出。显然,FreeDos不喜欢
int13h
作为第一个中断(?)。不知道为什么。我不记得以前见过这样的事。这个版本有一个稍微好一点的hexdump,也包括ascii,这应该可以更容易地判断您是否正在查看一个真正的引导扇区。我有一个想法,它不会在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

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
;--------------------
;nasm f-bin-o readmbr.com readmbr.asm
组织100小时
第2节bss
缓冲区resb512
第节.案文
; 完全没有意义的打断!
mov dl,13
mov啊,2
int 21h
mov-dx,80h;开车
mov-cx,1;部门(不是“部门”,傻瓜)
缓冲区
mov ax,201h;读一个扇区
int 13h
jc出口
; 将512字节转储为十六进制和ascii(如果可打印),每次16字节
缓冲区
莫夫迪,32岁;循环计数器
dumpem:
呼叫dump16
德克迪
jnz dumpem
出口:
ret
;------------------
;--------------------
; 将al中的字符打印到标准输出
; 返回:没有什么有用的
打印字符:
推斧
推送dx
mov dl,al
mov啊,2
int 21h
波普dx
爆斧
ret
;------------------
;--------------------
第16段:
; 以十六进制和ascii格式打印si指向的16个字节(如果可打印)
; 返回:si指向下一个字节。斧头,残废了。
莫夫cx,16
推硅;将其保存为ascii部分
顶部:
lodsb;al

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


好的。这是Linux版本的输出(比重新启动容易)。它“包裹”得很恐怖,但你可以看到它是“LILO”

FA EB 21 01 B2 01 4C 49 4C 4F 16 07 80 60 FC 47||ë!。².利洛.`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ü216; 1í184;…³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.“告诉我这在DosBox中有什么作用”:它打印一屏00。@Frank我现在没有访问我的DosBox的权限,一旦我有了它,我会告诉你的。@Frank刚刚找到这个链接,它使用aam16以十六进制打印,但不确定它对你有什么用处。嗨Frank,当我在DosBox中运行这个程序时,我可以看到hextump,我的意思是Hex值,但我如何才能确保它是我的硬盘引导扇区,我必须检查最后2个字节,其中包含签名值,将附加在我的Dosbox的屏幕截图中answer@Frank我试着把这些十六进制值解码成ascii码,看起来像是,它在打印你给出的代码,这就是这里所期望的吗?像个白痴一样,我忘了在我的“标签”中加上“组装”。谢谢你修好了,不管是谁做的。我是新来的,我能说什么?既不是全零,也不是发布的屏幕快照看起来像引导扇区。“DosBox”是虚拟的,可能看不到“真实”硬盘。(如果你能写到真正的硬盘上,就会严重违反安全!)我会重新启动到FreeDos,然后再试一次,这次不要那么“聪明”。)对我来说编写Linux程序更容易——完全不同的方法。我会再打给你的。感谢所有到目前为止的反馈@FrankKotler您是否可以将MBR的O/P连接到此处谢谢Frank,看起来我在这里运气不好,因为在运行Linux版本的时,我只能看到黑屏code@AmitSinghTomar好的,Linux版本,如果您在运行后立即键入
echo$?
,应该会打印一个错误号。13是我得到的最常见的一个——拒绝许可。这意味着我忘记了以root用户身份运行它,或者按照注释中的描述“烹饪”文件。2-无此类文件,6-无此类设备或地址,19-无此类设备。如果有必要,可以在errno.h中查找。如果它说0,我的代码就是错误。我认为判断您从哪个设备启动最简单的方法是键入
df
,然后查看“/”上安装了什么。勇气!fbkotler@myfairpoint.netHI弗兰克,我按照你的建议做了,echo$,输出结果为2意味着没有这样的文件,df的输出显示/dev/loop0挂载在“/”上。我应该如何理解它,/dev/loop0看起来不像是从硬盘启动的,或者是吗?我不知道如何理解/dev/loop0。听起来像是“虚拟启动”?如果你使用
文件名
,你会得到任何输出吗?非常感谢你,弗兰克。最后我想我可以看到硬盘的引导扇区了,我把文件名改成了/dev/sda3,它安装在/host上,把文件名改成/dev/loop0会给我带来很多0。我已经附上了linux版本的co的输出