MASM编译16位汇编多文件代码报错:符号未定义与块嵌套错误
16位汇编分文件编译报错(Symbol not defined/Block nesting error)解决
问题场景
学习16位汇编,尝试编写分文件代码并通过链接器生成.COM可执行文件,严格按教材步骤操作后,使用MASM编译时出现两个错误:
Symbol not definedBlock nesting error
已在子程序定义时使用PUBLIC声明ROUTINE_1为可被其他文件调用的符号,添加PROC NEAR指令后问题仍未解决。原代码及MASM输出如下:
原代码(CODIGO.asm)
;CODIGO.asm CODE_SEG SEGMENT PUBLIC ASSUME CS:CODE_SEG PUBLIC ROUTINE_1 MOV AH,02H MOV DL,41H INT 21H ROUTINE_1 ENDP CODE_SEG ENDS ENDS
MASM编译输出
C:\DOCUME~1\pedro>MASM.EXE CODE; The Microsoft MACRO Assembler Version 1.10, Copyright (C) Microsoft Inc. 1981,82 ?End of file encountered on input file PUBLIC ROUTINE_1 E r r o r --- 9:Symbol not defined ROUTINE_1 ENDP E r r o r --- 0:Block nesting error ?End of file encountered on input file Warning Severe Errors Errors 0 2
错误原因分析
ROUTINE_1符号未定义:只写了ROUTINE_1 ENDP,但没有对应的ROUTINE_1 PROC声明,汇编器无法识别该过程符号。- 块嵌套错误:
ENDP必须和PROC配对使用,缺少PROC会导致汇编器认为块结构不完整。 - 多余的段结束指令:代码末尾的空
ENDS属于无效指令,会干扰汇编器的段解析。 - 缺少入口点指定:未使用
END指令指定程序入口,汇编器无法确定程序起始位置,导致文件结束时报错。
修正后的代码
子程序文件(CODIGO.asm)
;CODIGO.asm - 子程序文件,提供可被外部调用的ROUTINE_1 CODE_SEG SEGMENT PUBLIC ASSUME CS:CODE_SEG ; 声明ROUTINE_1为公共符号,允许其他文件调用 PUBLIC ROUTINE_1 ; 定义ROUTINE_1过程(NEAR适合COM文件的近调用) ROUTINE_1 PROC NEAR MOV AH,02H ; DOS功能调用:显示字符 MOV DL,41H ; 字符'A'的ASCII码 INT 21H ; 执行DOS调用 RET ; 子程序返回 ROUTINE_1 ENDP CODE_SEG ENDS END ; 结束汇编(主文件才需要指定入口,子程序文件无需入口)
主文件(MAIN.asm)
分文件编译需搭配主文件调用子程序,才能生成完整的.COM文件:
;MAIN.asm - 主程序文件,调用CODIGO.asm中的ROUTINE_1 CODE_SEG SEGMENT PUBLIC ASSUME CS:CODE_SEG, DS:CODE_SEG ; 声明要调用的外部子程序 EXTRN ROUTINE_1:NEAR ; COM文件入口点,从CS:0开始执行 START: CALL ROUTINE_1 ; 调用外部子程序打印'A' MOV AH,4CH ; DOS功能调用:程序退出 INT 21H ; 执行退出 CODE_SEG ENDS END START ; 指定程序入口为START
编译与链接步骤
- 分别编译两个文件:
MASM MAIN.asm; MASM CODIGO.asm; - 链接生成.EXE后,转为.COM文件(需确保代码段从偏移0开始,且总大小不超过64KB):
LINK MAIN.OBJ CODIGO.OBJ; EXE2BIN MAIN.EXE MAIN.COM
内容的提问来源于stack exchange,提问作者Chines Free
相关产品推荐
相关产品推荐

