NASM - 对从磁盘加载的代码使用标签
NASM - Use labels for code loaded from disk
作为学习经验,我在我的 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
你可能会把它变得比现在更难(并不是说这无论如何都是微不足道的!)
您的标签工作正常,并将继续正常工作。请记住,如果您仔细查看生成的机器代码,您的短跳转(在您发布的 seg_two
之后的所有内容)都是 relative 跳转。这意味着汇编程序实际上不需要计算真实地址,它只需要计算当前操作码的偏移量。但是,当您将代码加载到 0x9000 处的 RAM 时,情况就完全不同了。
就我个人而言,当准确地编写您这样的代码时,我会将代码分开。引导扇区停在 dw 0xaa55
处,第二阶段获取其自己的文件,顶部带有 ORG 0x9000
。
将它们编译为目标代码时,只需将它们连接在一起即可。本质上,这就是您现在正在做的事情,只是您要让汇编程序为您做。
希望这是有道理的。 :)
作为学习经验,我在我的 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
你可能会把它变得比现在更难(并不是说这无论如何都是微不足道的!)
您的标签工作正常,并将继续正常工作。请记住,如果您仔细查看生成的机器代码,您的短跳转(在您发布的 seg_two
之后的所有内容)都是 relative 跳转。这意味着汇编程序实际上不需要计算真实地址,它只需要计算当前操作码的偏移量。但是,当您将代码加载到 0x9000 处的 RAM 时,情况就完全不同了。
就我个人而言,当准确地编写您这样的代码时,我会将代码分开。引导扇区停在 dw 0xaa55
处,第二阶段获取其自己的文件,顶部带有 ORG 0x9000
。
将它们编译为目标代码时,只需将它们连接在一起即可。本质上,这就是您现在正在做的事情,只是您要让汇编程序为您做。
希望这是有道理的。 :)