NASM中SECTION指令的VSTART=0参数为何未生效?
关于NASM忽略
VSTART=0参数的原因解析 核心原因
NASM的VSTART参数仅用于生成列表文件时的偏移显示基准,完全不会影响汇编阶段的实际地址计算逻辑。当你生成raw binary格式时,所有段会按顺序线性拼接,标签的地址始终是基于整个二进制文件开头的绝对偏移,而非每个段的VSTART设定值。
对你场景的具体分析
- 你的第一个
VSTART=0的段位于文件的0x200偏移处(前面有0x200字节的代码与数据) - 标签
continue在段内的逻辑偏移是0x25,但它在整个二进制文件中的绝对偏移是0x200 + 0x25 = 0x225 - 远跳转指令
jmp 0x10:continue中的偏移部分,NASM会直接使用这个绝对偏移值(小端存储为0x25 0x02),最终跳转目标就变成了0x10:0x225,和你在Bochs中观察到的一致。
解决方法:手动实现段内偏移计算
如果需要跳转目标使用段内的VSTART基准偏移,你需要手动计算段内相对地址,常用方式有两种:
- 直接使用
$ - $$表示当前位置相对于段起始的偏移($$代表当前段在文件中的绝对起始地址) - 定义宏简化地址转换:
之后跳转指令可以写成:%define seg_offset(label) (label - $$)
这样就能得到你预期的jmp 0x10:seg_offset(continue)0x25偏移值。
额外说明
raw binary格式本身没有段结构,所有内容都是连续的字节流。NASM对raw binary的处理不会进行任何段重定位操作,VSTART只是列表文件里的“显示辅助”,不具备修改地址计算的功能。
内容的提问来源于stack exchange,提问作者Ruslan
相关产品推荐
相关产品推荐

