8051汇编代码索引故障求助:所有字符均显示为A的问题分析
8051汇编索引问题:所有字符显示为'A'的修复方案
核心问题
无论向Text中写入任何字符,程序始终输出字符'A'的摩斯码,需定位问题并修复。
原代码
主程序代码
Start: mov R0, #00h ; 初始化文本索引计数器 Morse: mov DPTR, #Text ; 指向文本起始地址 mov A, R0 ; 将偏移量存入累加器A NextChar: cjne R0, #00h, LetterSpaceCALL jmp Continue0 Continue0: movc A, @A+DPTR ; 从文本中加载一个字符到A inc R0 cjne A, #'.', nextTest01 ; 检查是否为结束符'.' jmp endProgram nextTest01: cjne A, #' ', nextTest02 jmp WordSpace ; 处理单词间空格 nextTest02: jz EndProgram ; 检查是否为字符串结束符(空字符) ; A中为待解码的字符 Char: orl A, #20h ; 转换为小写 clr C ; 清除ORL操作后的进位标志 subb A, #'a' ; 计算字符的序号(a=0) mov DPTR, #ASCII_TO_MORSE_TABLE ; 指向摩斯码表起始 ; 查找当前字符对应的摩斯码起始位置 morseCode: clr A movc A, @A+DPTR ; 读取当前DPTR指向的字符 inc dptr ; 指针后移 cjne A, #'!', nextTest03 ; 检查是否为分隔符'!' jmp Morse ; 找到分隔符,处理下一个文本字符 nextTest03: call VoidCall cjne A, #'-', DotCall ; 判断是点还是划 jmp DashCall jmp morseCode DotCall: call DOT jmp morseCode DashCall: call DASH jmp morseCode VoidCall: call Void ret WordSpace: call NEXT_WORD ; 单词间延迟 jmp Morse LetterSpaceCALL: call LetterSpace jmp Continue0 EndProgram: clr GREEN_LED
数据段代码
Text: db 'sos.' ASCII_TO_MORSE_TABLE:db '.-!', '-...!', '-.-.!', '-..!', '.!', '..-.!', '--.!', '....!', '..!', '.---!', '-.-!', '.-..!', '--!', '-.!', '---!', '.--.!', '--.-!', '.-.!', '...!', '-!', '..-!', '...-!', '.--!', '-..-!', '-.--!', '--..!' ; | a | | b | | c | | d | |e| | f | | g | | h | | i | | j | | k | | l | | m | | n | | o | | p | | q | | r | | s | | t | | u | | v | | w | | x | | y | | z |
问题分析
未正确定位目标字符的摩斯码起始位置
代码计算出字符序号后,直接将DPTR指向摩斯码表开头,没有根据序号偏移到对应字符的摩斯码起始地址。每次进入morseCode段时,都会从表的第一个字符('a'的摩斯码)开始读取,导致所有字符都输出'A'的摩斯码。摩斯码遍历逻辑缺失地址定位步骤
没有通过字符序号跳过表中前面的字符条目,直接从表头读取,完全忽略了索引计算的结果。
修复方案
修改Char段代码,增加根据字符序号定位摩斯码起始位置的逻辑:
; A中为待解码的字符 Char: orl A, #20h ; 转换为小写 clr C ; 清除进位标志 subb A, #'a' ; 计算字符的序号(a=0,s=18) mov R1, A ; 保存序号到R1 mov DPTR, #ASCII_TO_MORSE_TABLE ; 指向摩斯码表起始 find_start: ; 循环查找目标字符的摩斯码起始位置 clr A movc A, @A+DPTR cjne A, #'!', find_next ; 不是分隔符,指针后移 djnz R1, find_start ; 序号减1,未到0则继续找下一个分隔符 inc DPTR ; 跳过分隔符,指向当前字符的摩斯码开头 jmp morseCode find_next: inc DPTR jmp find_start
修复逻辑说明
- 用
R1保存计算得到的字符序号,通过循环遍历摩斯码表 - 每遇到一个分隔符'!',就将
R1减1,直到R1为0,此时DPTR指向当前字符的分隔符位置 - 最后将
DPTR加1,跳过分隔符,定位到目标字符的摩斯码起始地址,后续morseCode段就会读取正确的摩斯码内容
额外注意事项
- 原代码中
endProgram和EndProgram拼写不一致,建议统一为EndProgram避免混淆 - 确保文本结束符'.'的判断逻辑正确,避免提前终止程序
内容的提问来源于stack exchange,提问作者JAJAJa Jajajaaa
相关产品推荐
相关产品推荐

