MASM引导加载器中使用字符串变量触发未定义符号错误
MASM引导加载器编译报错:未定义符号
bootInfo及参数类型不匹配 问题分析
编译时出现的A2006: undefined symbol : bootInfo是核心错误,A2114参数类型不匹配是前者导致的连锁问题。原因是MASM汇编器从上到下逐行处理代码,当汇编到INVOKE Print, OFFSET bootInfo时,bootInfo变量还未被定义,汇编器无法识别该符号。
尽管使用了TINY内存模型(代码段与数据段合并),但这并不改变汇编器的符号解析顺序——未提前声明或定义的符号,在首次被引用时会被判定为未定义。
修复方案
方案1:将变量移至引用位置之前
最直接的修复方式是把bootInfo变量的定义移到_start入口点之前,确保汇编器在处理引用时已经识别到该符号:
.386 option segment:use16 .model tiny, stdcall .code org 07c00h Print PROTO lpStr:WORD ; 将数据定义提前至入口点前 bootInfo db "Booting CompatOS...", 0 _start: INVOKE Print, OFFSET bootInfo cli hlt error: cli hlt Print PROC USES ax si lpStr:WORD mov si, lpStr mov ah, 0Eh @@loop: lodsb cmp al, 0 je @@done int 10h jmp @@loop @@done: ret Print ENDP ; 填充引导扇区至512字节 byte 510-($-_start) dup (0) dw 0AA55h END _start
方案2:使用符号声明实现向前引用
如果不想调整变量位置,可以通过EXTRN(向前声明)和PUBLIC(标记符号为公共)让汇编器识别未定义的符号:
.386 option segment:use16 .model tiny, stdcall .code org 07c00h Print PROTO lpStr:WORD ; 向前声明bootInfo为外部字节型符号 EXTRN bootInfo:BYTE _start: INVOKE Print, OFFSET bootInfo cli hlt error: cli hlt Print PROC USES ax si lpStr:WORD mov si, lpStr mov ah, 0Eh @@loop: lodsb cmp al, 0 je @@done int 10h jmp @@loop @@done: ret Print ENDP ; 标记bootInfo为公共符号并定义 PUBLIC bootInfo bootInfo db "Booting CompatOS...", 0 ; 填充引导扇区至512字节 byte 510-($-_start) dup (0) dw 0AA55h END _start
验证说明
你的编译命令(ml /AT /c、link /TINY)是正确的,符合TINY模型引导加载器的编译要求。修改后重新执行Makefile,即可解决编译错误。
内容的提问来源于stack exchange,提问作者Albert Wesker
相关产品推荐
相关产品推荐

