【发布时间】:2016-08-08 21:53:52
【问题描述】:
以下源文件分别组装(成原始二进制文件)并分别加载到虚拟软盘的扇区 1 和 2。然后这张软盘作为 qemu-system-i386 VM 的引导介质。
“引导加载程序”从软盘的第 2 扇区读取“第一个程序”,然后跳转到包含刚刚读取的代码的内存。以下代码按需要工作(即打印“第一个程序”欢迎消息),但我必须在“第一个程序”的源代码中指定 ORG 0x001E(通过在十六进制编辑器中检查引导加载程序的代码获得)。 0x001E 是temp 缓冲区的偏移量,它保存着从软盘读取的代码。
“引导加载程序”:
BITS 16
bootloader_main:
mov bx, 0x07C0 ; Set data segment to bootloader's default segment
mov ds, bx
mov ah, 0x02 ; BIOS int13h "read sector" function
mov al, 1 ; Number of sectors to read
mov cl, 2 ; Sector to read
mov ch, 0 ; Cylinder/track
mov dh, 0 ; Head
mov dl, 0 ; Disk number (here, the floppy disk)
mov bx, 0x07C0 ; Segment containing the destination buffer
mov es, bx
mov bx, temp ; Destination buffer offset
int 0x13
jmp temp
ret
;end bootloader_main
temp: times 60 db 17
times 510-($-$$) db 0 ; Pad rest of sector and add bootloader
dw 0xAA55 signature
“第一个程序”:
BITS 16
ORG 0x001E ; Assume that this code will be located 0x001E bytes
after start of bootloader (in RAM)
mov bx, string ; Print a welcome string
mov ah, 0x0E
print_loop:
mov al, byte [bx]
int 0x10
inc bx
cmp byte [bx], 0
jne print_loop
;end print_loop
string: db "This is the first program.", 0
或者,我可以使用ORG 0x200 和0x200 作为缓冲区而不是temp(即在引导加载程序之后将程序加载到RAM),但是在创建有用的操作时,这些黑客似乎都不可持续系统。如何避免这种地址硬编码?
【问题讨论】:
-
发布汇编问题时请标记处理器架构。
-
我想基地址是需要用引导加载程序指定的。我在这方面的大部分工作都是在嵌入式系统上进行的,我知道 BIOS 为您做了很多事情。对我来说,当我使用引导加载程序时,它通常有文档告诉我预期的入口点在哪里。
-
因此,如果有人正在组装一个程序,该程序将被加载到软盘上并由引导加载程序读取,他们会被告知在他们的源代码中添加类似
ORG 512(或其他一些明确的地址)的东西?并且引导加载程序总是将程序加载到内存的同一部分?很难想象现代操作系统是如何由此演变而来的,但我想我应该去阅读更多有关历史的信息。 -
再说一次,我的经验是使用嵌入式系统,所以如果我从 NXP 获得一个引导加载程序来安装 Kinetis 部件,文档会告诉我引导加载程序将从 0x0000 放置到 0x3fff,并且我需要链接我的程序以使其入口点的地址位于 0x4000。分段的技巧是在您的情况下有意义的方式,但这是大多数嵌入式系统中没有的功能。
标签: assembly nasm x86-16 bootloader position-independent-code