汇编冒泡排序编译报错:Label STARTASC未定义,求原因分析
汇编冒泡排序代码报错「Label STARTASC is not defined」的原因分析
核心原因
- 单遍扫描汇编器的解析限制:代码开头用
JMP STARTASC跳转到升序排序逻辑,但STARTASC标签定义在降序排序代码块的HLT指令之后。部分老式8085汇编器采用单遍扫描模式,从前往后处理代码时,遇到JMP STARTASC还没扫描到后面的STARTASC标签,因此判定该标签未定义。 - 死代码误判:降序排序块末尾的
HLT会终止程序,部分汇编器会把HLT之后的代码认定为不可达的死代码,直接跳过这部分的标签解析,导致STARTASC标签未被识别。
修复方案
- 调整代码顺序:把升序排序的
STARTASC代码块移到降序排序的STARTDESC代码块前面,让汇编器在处理JMP STARTASC之前就解析到STARTASC标签。 - 提前声明标签:如果使用的汇编器支持标签预声明(比如部分工具支持用
PUBLIC伪指令),可以在代码开头先声明STARTASC标签。
修正后的代码示例
MVI H, 00H MOV A, M ; 加载0000H地址的控制值到累加器 CPI 00H ; 与00H比较 JZ STARTDESC ; 相等则跳转到降序排序 JMP STARTASC ; 否则跳转到升序排序 STARTASC: LXI H, 2500H ; 加载数组长度的内存地址 MVI B, 00H ; 将寄存器B置0 MOV C, M ; 把数组长度存入寄存器C DCR C ; C自减(冒泡排序的比较轮次-1) INX H ; 指针后移,指向数组第一个元素 CHECKASC: MOV A, M ; 将当前元素存入累加器 INX H ; 指针后移,指向下一个元素 CMP M ; 比较当前元素与下一个元素 JC NEXTASC ; 当前元素更小则跳过交换 JZ NEXTASC ; 元素相等也跳过交换 MOV D, M ; 交换两个元素 MOV M, A ; DCX H MOV M, D ; INX H MVI B, 01H ; 标记本轮发生了交换 NEXTASC: DCR C ; 比较次数减1 JNZ CHECKASC ; 未完成所有比较则继续 MOV A, B ; 将交换标记存入累加器 CPI 01H ; 检查是否发生过交换 JZ STARTASC ; 发生过交换则重新排序 HLT ; 排序完成,程序终止 STARTDESC: LXI H, 2500H ; 加载数组长度的内存地址 MVI B, 00H ; 将寄存器B置0 MOV C, M ; 把数组长度存入寄存器C DCR C ; C自减 INX H ; 指针后移,指向数组第一个元素 CHECKDESC: MOV A, M ; 将当前元素存入累加器 INX H ; 指针后移,指向下一个元素 CMP M ; 比较当前元素与下一个元素 JNC NEXTDESC ; 当前元素更大则跳过交换 MOV D, M ; 交换两个元素 MOV M, A ; DCX H MOV M, D ; INX H MVI B, 01H ; 标记本轮发生了交换 NEXTDESC: DCR C ; 比较次数减1 JNZ CHECKDESC ; 未完成所有比较则继续 MOV A, B ; 将交换标记存入累加器 CPI 01H ; 检查是否发生过交换 JZ STARTDESC ; 发生过交换则重新排序 HLT ; 排序完成,程序终止
内容的提问来源于stack exchange,提问作者seven8l
相关产品推荐
相关产品推荐

