我正在尝试开发一个非常简单的引导程序,我正在关注tutorial用于此目的。我的问题是关于寻址和org
命令。
我理解为什么需要org
命令来获取给定地址的数据。由于引导扇区将在地址0x7c00处加载,因此需要通知编译器该地址应添加到任何引用。例如,如果没有[org 0x7c00]
命令,下面的代码将无法工作,因为它将获取地址0x0012而不是0x7c12的数据。
[org 0x7c00]
; print String
mov ah, 0x0e
mov bx, text
printLoop:
mov al,[bx]
cmp al,0
je loop
int 0x10
inc bx
jmp printLoop
loop:
jmp loop
text: ; at address 0x0012 in the file but will be loaded at 0x7c12
db 'Loading OSiris operating system...',10,13,0
times 510-($-$$) db 0
dw 0xaa55
现在我不明白为什么jmp
命令不一样?总之,我不明白为什么下面的代码工作(无限打印?,org
命令评论)。
;[org 0x7c00]
mov ah, 0x0e
mov al, '?'
loop: ; as I understood 0x0004 in the file but 0x7c04 in the memory
int 0x10
jmp loop ; hence this should jump at 0x0004 and the code should not work (but it actually works)
times 510-($-$$) db 0
dw 0xaa55
根据我的理解,应该进行跳转以寻址0x0004。因此,计算机应该无限启动,而不仅仅是打印“?”。它是否与本地跳转和代码段有关?
这种形式的短jmp
使用相对偏移进行编码。它基本上说“跳回4个字节”。因此,它是独立的,无论如何都可以。实际的机器代码是EB FC
,其中EB
是短跳的操作码,FC
是-4
,偏移量从下一条指令的地址计算,执行通常会继续。
另请注意,入口点仅保证在物理地址0x7c00,您不应该依赖于0:0x7c00
。一些BIOS可能会使用0x7c0:0
。为了安全起见,您应该初始化段寄存器,包括CS
(使用远程跳转)。