NASM编译时data段被填充至512字节,代码段起始地址异常求助
问题原因及解决方法
你的问题出在多个段都指定了VSTART=0,NASM在bin格式下会将每个带VSTART的段视为独立的虚拟地址空间,为了避免虚拟地址范围重叠,会自动填充数据将后续段移到不重叠的位置,这就是data段和code段之间出现150字节填充的原因。
具体逻辑:
.text段未指定VSTART,默认虚拟起始地址为0,占用虚拟地址0-200,对应输出文件偏移0-200。data段指定VSTART=0,虚拟起始地址0会和.text的虚拟地址范围重叠,NASM自动将其输出位置移到.text结束的200偏移处,此时data段的虚拟地址实际对应200-250。code段同样指定VSTART=0,又会和前面两段的虚拟地址范围重叠,NASM便将其输出位置移到下一个“安全”边界(400偏移),导致中间出现填充。
解决步骤
去掉不必要的
VSTART=0
如果你不需要段内符号从0开始计算,直接删除所有段定义中的VSTART=0,NASM会按代码顺序将段拼接,code段会从250偏移开始(如果保留data段结尾的ALIGN 16,则会对齐到256偏移)。修改后的段定义示例:
[SECTION data] BITS 32 ... ; some data ; 若不需要对齐到16字节,可删除下面这行 ALIGN 16 [SECTION code] ... ; some code ALIGN 512若必须保留
VSTART=0,使用AT指定输出偏移
如果你需要段内符号从0开始计算,同时希望段按顺序拼接,需用AT关键字明确指定每个段在输出文件中的偏移:; .text段结束在200偏移,所以data段指定AT 200 [SECTION data AT 0x200] VSTART=0 BITS 32 ... ; some data ALIGN 16 ; data段实际长度50,若保留ALIGN 16则长度为64,所以code段指定AT 0x240(200+64) [SECTION code AT 0x240] VSTART=0 ... ; some code ALIGN 512检查
ALIGN指令的影响
你在data段结尾的ALIGN 16会将data段的长度对齐到16字节(50字节会被填充到64字节),如果不需要这个对齐,直接删除该行即可让code段从250偏移开始。
内容的提问来源于stack exchange,提问作者Ruslan
相关产品推荐
相关产品推荐

