解释引导扇区汇编代码

问题描述

我正在浏览 Nick Blundell 的 os-dev。在使用NASM编译引导扇区汇编代码后,他在那里查看了bin文件中的十六进制数据。有没有办法手动解释所有512字节,只需查看代码。比如说,下面是代码

mov ah,0x0E

;First attempt
mov al,the_secret
int 10h

;Second attempt
mov al,[the_secret]
int 10h

;Third attempt
mov bx,the_secret
add bx,0x7c00
mov al,[bx]
int 10h

;Fourth attempt
mov al,[0x7c1e]
int 0x10

jmp $

the_secret: db "X"

times 510 - ($ - $$) db 0

dw 0xaa55

以上代码编译后生成一个512字节的bin文件。是否可以仅通过查看代码来确定所有 512 个字节?我认为这应该是可能的,否则他不会知道 the_secret 存在于 0x7c1e。 如果可能,请指导我阅读解释这一部分的相关文章。谢谢

解决方法

您是否尝试过使用 ndisasm foo.bin?您会发现 mov bx,0x1d 包含机密地址,以及另一个 mov al,[0x7c1e]。然后,您将查看该地址(0x7c00 加载地址)处的反汇编,并查看字节。而且,它是无限循环跳转后的第一个字节,这也使它在一个很明显的地方。

$ nasm foo.asm
$ ndisasm foo
00000000  B40E              mov ah,0xe
00000002  B01D              mov al,0x1d        ; use the address as an ASCII code...
00000004  CD10              int 0x10
00000006  A01D00            mov al,[0x1d]
00000009  CD10              int 0x10
0000000B  BB1D00            mov bx,0x1d
0000000E  81C3007C          add bx,0x7c00
00000012  8A07              mov al,[bx]
00000014  CD10              int 0x10
00000016  A01E7C            mov al,[0x7c1e]
00000019  CD10              int 0x10
0000001B  EBFE              jmp short 0x1b
0000001D  58                pop ax               ;;; This 0x58 is actually the ASCII code
0000001E  0000              add [bx+si],al
00000020  0000              add [bx+si],al
...
000001FE  55                push bp
000001FF  AA                stosb

看起来这个引导加载程序在启动时假定 DS = 0,但实际上并不打算将 DS 本身设置为匹配隐式默认值 org 0。较早的 mov al,[0x1d] 将适用于 DS=0x07C0 的另一个可能的情况。 (引导加载程序通常以 CS:IP = 07C0:00000000:7C00 开头,但我不确定 DS 是否通常设置为任何相关内容。最好假设没有。)

此外,从您发布的来源来看,秘密位于二进制文件的 0x1d 偏移处,而不是 0x1e。所以 mov al,[0x7c1e] 是错误的。 mov al,[0x7c00 + the_secret] 应该是有意义的,并会进行调整以适应标签的最终位置。