作为一种学习经历,我在我的x86仿真器Qemu中以16位实模式为NASM编写BIOS启动加载程序。
BIOS将您的引导扇区加载到地址0x7C00
。 NASM假设您从0x0
开始,因此除非您使用[org 0x7C00]
(或可能是其他技术)指定原点,否则您的标签将毫无用处。但是,当你加载第二阶段引导加载程序时,它的RAM原点是不同的,这使得在新加载的代码中使用标签的地狱变得复杂。
推荐的解决方法是什么?这个链接器领域?我应该使用段寄存器而不是org
吗?
提前致谢!
P.S。这是现在可以使用的代码:
[bits 16]
[org 0x7c00]
LOAD_ADDR: equ 0x9000 ; This is where I'm loading the 2nd stage in RAM.
start:
mov bp, 0x8000 ; set up the stack
mov sp, bp ; relatively out of the way
call disk_load ; load the new instructions
; at 0x9000
jmp LOAD_ADDR
%include "disk_load.asm"
times 510 - ($ - $$) db 0
dw 0xaa55 ;; end of bootsector
seg_two:
;; this is ridiculous. Better way?
mov cx, LOAD_ADDR + print_j - seg_two
jmp cx
jmp $
print_j:
mov ah, 0x0E
mov al, 'k'
int 0x10
jmp $
times 2048 db 0xf
答案 0 :(得分:1)
你可能会比这更难(不是说这无关紧要!)
您的标签工作正常,并将继续正常工作。请记住,如果您在生成的机器代码下查看内容,您的短跳(seg_two
之后的所有内容都是相对跳转。这意味着汇编程序实际上不需要计算实际地址,它只需要计算当前操作码的偏移量。但是,当您将代码加载到RAM为0x9000时,这是一个完全不同的故事。
就个人而言,在准确编写您所使用的代码时,我会将代码分开。引导扇区停在dw 0xaa55
,第二阶段获取自己的文件,顶部有ORG 0x9000
。
当您将这些编译为目标代码时,您只需将它们连接在一起即可。从本质上讲,这就是你现在正在做的事情,除非你让汇编程序为你做这件事。
希望这是有道理的。 :)