You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

16位无符号整数转ASCII十六进制字符串代码覆盖问题修复问询

修复16位无符号整数转十六进制ASCII字符串的覆盖问题

需求说明

将16位无符号整数转换为4位十六进制ASCII字符串:

  • 输入:数值高字节存于R5,低字节存于R6;ASCII字符串起始地址由R7指定,初始化代码为MOV R5,#HIGH(NUMBER)、MOV R6,#LOW(NUMBER)、MOV R7,#STR_ADDR_IRAM
  • 输出:从R7指向的内存地址开始,连续存储转换后的4位十六进制ASCII字符(可选添加字符串结束符)

现有问题

当前代码的十六进制转ASCII逻辑本身可行,但存在核心问题:每次转换得到的字符直接覆盖寄存器R7的数值,而非写入R7指向的内存地址;同时未更新指针地址,导致最终仅保留最后一个转换的字符,前面的结果全部丢失。

原代码

MOV A, R6                    ;Get hexadecimal data byte from RAM location R6                   
    MOV R2, A                    ;Store in R2                  
    ANL A, #0FH                  ;Get the lower nibble               
    ACALL ASCII                  ;Convert to ASCII                    
    MOV R7, A                    ;Store the lower digit's ASCII code            
    MOV A, R2                    ;Get back the number              
    SWAP A                       ;Swap nibbles in A                  
    ANL A, #0FH                  ;Get the upper BCD digit               
    ACALL ASCII                  ;Convert to ASCII                      
    MOV R7, A                    ;Store the upper digit´s ASCII code          
    MOV A, R5                    ;Get hexadecimal data byte from RAM location R5                   
    MOV R2, A                    ;Store in R2                    
    ANL A, #0FH                  ;Get the lower nibble                 
    ACALL ASCII                  ;Convert to ASCII                
    MOV R7, A                    ;Store the lower digit's ASCII code           
    MOV A, R2                    ;Get back the number                  
    SWAP A                       ;Swap nibbles in A                         
    ANL A, #0FH                  ;Get the upper BCD digit                
    ACALL ASCII                  ;Convert to ASCII                        
    MOV R7, A                    ;Store the upper digit´s ASCII code            
    RET                                       
    ASCII : CLR C                ;ASCII conversion                      
            MOV R4, A            ;Store A to R4                      
            SUBB A, #0AH         ;Substract accumulator                        
            JC next              ;If carry, jump to next                         
            MOV A, R4            ;No carry so bring back R4 to A                   
            ADD A, #07H          ;No carry, so add 7 to A                     
            SJMP SUM             ;Jump to SUM                     
            next:   MOV A, R4    ;Bring back R4 to A                   
            SUM:    ADD A, #30H  ;Add 30 to A                     
    RET                             
    END                            

修复后的代码

MOV A, R5                    ; 获取16位整数的高字节
    MOV R2, A                    ; 暂存高字节数据到R2
    SWAP A                       ; 交换高低四位,先处理高字节的高四位(对应十六进制第1位)
    ANL A, #0FH                  ; 提取高四位
    ACALL ASCII                  ; 转换为ASCII码
    MOV @R7, A                   ; 将ASCII字符写入R7指向的内存地址
    INC R7                       ; 指针地址自增,准备存储下一个字符
    
    MOV A, R2                    ; 取回暂存的高字节数据
    ANL A, #0FH                  ; 提取高字节的低四位(对应十六进制第2位)
    ACALL ASCII                  ; 转换为ASCII码
    MOV @R7, A                   ; 写入内存
    INC R7                       ; 更新指针

    MOV A, R6                    ; 获取16位整数的低字节
    MOV R2, A                    ; 暂存低字节数据到R2
    SWAP A                       ; 交换高低四位,处理低字节的高四位(对应十六进制第3位)
    ANL A, #0FH                  ; 提取高四位
    ACALL ASCII                  ; 转换为ASCII码
    MOV @R7, A                   ; 写入内存
    INC R7                       ; 更新指针

    MOV A, R2                    ; 取回暂存的低字节数据
    ANL A, #0FH                  ; 提取低字节的低四位(对应十六进制第4位)
    ACALL ASCII                  ; 转换为ASCII码
    MOV @R7, A                   ; 写入最后一个字符
    ; 可选:添加字符串结束符(若需要C风格字符串)
    ; MOV A, #00H
    ; MOV @R7, A
    RET                                       

ASCII : CLR C                ; 十六进制转ASCII子程序
        MOV R4, A            ; 暂存当前数值到R4
        SUBB A, #0AH         ; 比较数值是否≥10
        JC next              ; 若数值<10(有进位),跳转到next
        MOV A, R4            ; 数值≥10,取回原数值
        ADD A, #07H          ; 加上偏移量,转换为A-F的ASCII码
        SJMP SUM             ; 跳转到统一加30H的步骤
next:   MOV A, R4            ; 数值<10,取回原数值
SUM:    ADD A, #30H          ; 加上30H,转换为0-9的ASCII码
        RET                             
END                            

修复要点

  • 写入内存而非覆盖寄存器:将MOV R7, A替换为MOV @R7, A,这是8051汇编中间接寻址的写法,用于将累加器A的值写入到R7寄存器指向的内存单元,而非修改R7本身的指针值。
  • 更新指针地址:每次写入字符后执行INC R7,让指针指向内存中的下一个单元,确保后续字符不会覆盖已写入的结果。
  • 调整转换顺序:原代码的转换顺序不符合16位整数的十六进制显示逻辑(原顺序为低字节低四位→低字节高四位→高字节低四位→高字节高四位),修复后调整为高字节高四位→高字节低四位→低字节高四位→低字节低四位,保证输出的ASCII字符串顺序与数值的十六进制表示一致。

内容的提问来源于stack exchange,提问作者Tomás Prieto Calabuig

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 11:20:40