Assembly nasm中的标签偏移

Assembly nasm中的标签偏移,assembly,x86,nasm,x86-16,Assembly,X86,Nasm,X86 16,我试图为x86编写一个简单的引导加载程序,但在理解NASM在组装程序时如何将标签转换为偏移量时遇到了一个问题 (这只是一个示范项目) 我使用nasm-f bin命令组装了代码。但它并没有像预期的那样起作用。我在二进制输出上使用了objdump-b binary-m i8086-m intel-D,发现与mov si、msg和call print对应的行被转换为: mov si,0x7c0d call 0xc 因此,当NASM用偏移量值替换mov si中的msg时,它使用相对于0x00

我试图为x86编写一个简单的引导加载程序,但在理解NASM在组装程序时如何将标签转换为偏移量时遇到了一个问题

(这只是一个示范项目)

我使用
nasm-f bin
命令组装了代码。但它并没有像预期的那样起作用。我在二进制输出上使用了
objdump-b binary-m i8086-m intel-D
,发现与
mov si、msg
call print
对应的行被转换为:

mov    si,0x7c0d
call   0xc

因此,当NASM用偏移量值替换
mov si中的
msg
时,它使用相对于
0x0000
的绝对偏移量,但当它将
print
中的
call print
转换为偏移量时,它使用相对于
cs
的偏移量,即
0x07C0
。因此,当我试图打印字符时,
[ds:si]
没有指向预期的位置。问题是为什么?如果我做错了,正确的方法是什么?

这是反汇编程序的人工制品:它将相对位移转换为绝对地址。
如果将其作为原点传递0x7c00,它将显示正确的值

c:\>ndisasm -b 16 -o 7c00h a
00007C00  B8C007            mov ax,0x7c0
00007C03  8ED8              mov ds,ax
00007C05  BE0D7C            mov si,0x7c0d
00007C08  E80100            call word 0x7c0c
00007C0B  F4                hlt
00007C0C  C3                ret
NDISAM示例

错误在于您正在为
ds
使用0x7c0,从
ds
中可以看出,使用该值,代码的原点为零,而不是0x7c0

例如,
start
位于原点,对于0x7c00的NASM和
mov si,start
组合为
mov si,0x7c00

运行时,
start
位于线性地址0x07c00,但由于初始化了
ds
的方式,指针
[ds:si]
指向0x07c0:0x7c00=0x0f800

您可以使用零初始化
ds
[ds:si]
将指向0x0000:0x7c00=0x07c00)或将原点设置为零(
[ds:si]
将指向0x07c0:0x0000=0x07c00)

作为旁注:对于
cs
和其他段,您可以使用不同的值,但这是您必须记住并注意的事情,例如,当您移动代码或设置ISR时。
但是,必须初始化所有段寄存器,包括
ss:sp

如果这是您第一次使用引导加载程序,我建议您使用与ds相同的
cs


无论如何,如果您想尝试不同的值,NASM支持
bin
输出格式,这是它支持的最接近分段的东西

调用
在机器代码中具有相对imm16偏移量
+0x0001
,因此它正好指向
hlt
之后,并且将工作。顺便说一句,使用far
jmp 0000:7C00+
启动引导加载程序代码是一种很好的做法,以确保
cs:ip
对此进行“规范化”,因为一些BioSe会以不同的变体启动引导加载程序,如
07C0:0000
,因此,通过
cs
进行的所有绝对偏移量和寻址在这样的BIOS中都是错误的。问题是我没有完全理解
org
指令的作用。因此,源代码和段寄存器之间的不一致…。@Kia.celever很高兴知道问题现在已经解决:)出于好奇,我可以问一下您对ORG指令的错误解释是什么吗?我有时会教这些东西,这会帮助我了解一些常见的陷阱。我不知道org指令中的值实际上应该是相对于当前段的“偏移量”。我认为这是程序将要驻留的绝对(20位宽)物理地址。谢谢@Kia.celever的输入。
c:\>ndisasm -b 16 -o 7c00h a
00007C00  B8C007            mov ax,0x7c0
00007C03  8ED8              mov ds,ax
00007C05  BE0D7C            mov si,0x7c0d
00007C08  E80100            call word 0x7c0c
00007C0B  F4                hlt
00007C0C  C3                ret