解释引导扇区汇编代码
Interpreting the boot sector assembly code
我正在阅读 Nick Blundell 的 os-dev。在使用 NASM 编译 引导扇区 汇编代码后,他在 bin 文件 中获取了 hex 数据。有没有办法通过查看代码手动解释所有 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文件。 pos是不是光看代码就能确定所有的512字节?我觉得应该是possible,不然他不会知道the_secret出现在0x7c1e。
如果是possible,请指导我阅读解释这部分的相关文章。谢谢
您尝试过使用 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:0000
或 0000:7C00
开头,但我不确定 DS 通常是否设置为相关的任何内容。最好假设没有。)
此外,根据您发布的源代码,秘密位于二进制文件的 0x1d
偏移处,而不是 0x1e
。所以 mov al,[0x7c1e]
是错误的。 mov al, [0x7c00 + the_secret]
会有意义并进行调整以适应标签结束的位置。
我正在阅读 Nick Blundell 的 os-dev。在使用 NASM 编译 引导扇区 汇编代码后,他在 bin 文件 中获取了 hex 数据。有没有办法通过查看代码手动解释所有 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文件。 pos是不是光看代码就能确定所有的512字节?我觉得应该是possible,不然他不会知道the_secret出现在0x7c1e。 如果是possible,请指导我阅读解释这部分的相关文章。谢谢
您尝试过使用 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:0000
或 0000:7C00
开头,但我不确定 DS 通常是否设置为相关的任何内容。最好假设没有。)
此外,根据您发布的源代码,秘密位于二进制文件的 0x1d
偏移处,而不是 0x1e
。所以 mov al,[0x7c1e]
是错误的。 mov al, [0x7c00 + the_secret]
会有意义并进行调整以适应标签结束的位置。