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

如何修改汇编代码实现输入与QUIT比较,解决程序停滞问题?

字符串比较逻辑导致程序停滞的问题排查与修复

我需要实现用户输入与"QUIT"的比较功能,要求输入与"QUIT"不匹配时退出循环。但实际运行程序时,无论输入什么内容,程序都会停滞。已经尝试调整代码执行顺序、使用调试器排查,仍未定位到具体问题。相关循环的汇编代码如下:

; 字符串比较函数
STRING_COMPARE_QUIT AND R0, R0, #0 ; 初始化结果为0
    ; R1指向'QUIT',R2指向输入缓冲区
    ; R3/R4为字符串中的字符
    ; R5是比较标志,R6用于小写检查
    ; R6是小写掩码
    CASE_INSENSITIVE_COMPARE_QUIT
        LEA   R1, QUIT           ; 指向字符串"QUIT"
        LD    R2, INPUT_BUFFER   ; 指向输入缓冲区
        AND   R5, R5, #0         ; 清除比较标志

        CHECK_LOOP_QUIT
            LDR   R3, R1, #0         ; 从"QUIT"加载字符
            LDR   R4, R2, #0         ; 从输入缓冲区加载字符

            ; 检查R3是否为小写,若是则转为大写
            LD    R6, MASK     ; 将小写掩码值加载到R6
            AND   R6, R3, R6         ; 用掩码判断是否为小写字母
            BRz   NOT_LOWERCASE_1_QUIT    ; 零标志表示不是小写字母
            ADD   R3, R3, #0         ; 根据R3设置条件码
            BRn   NOT_LOWERCASE_1_QUIT    ; 负标志表示不是小写字母(ASCII < 'a')
            BRzp  CASE_CHECK_R3_QUIT      ; 零或正表示是小写字母
            NOT_LOWERCASE_1_QUIT
            BRnzp SKIP_CONVERSION_1_QUIT  ; 不是小写则跳过转换
            
            CASE_CHECK_R3_QUIT
                LD    R6, MASK           ; 从内存加载32到R6
                AND   R6, R3, R6         ; 用掩码检查R3是否为小写
                BRz   CONVERT_R3_QUIT         ; 若为零,将小写转为大写
                ; 由于此处BRnzp是无条件跳转,该标签已无必要
                SKIP_CONVERSION_1_QUIT    ; 后续可移除该行,除非添加新代码
                BRnzp NEXT_INSTRUCTION_QUIT   ; 无需转换则跳转到下一条指令
                CONVERT_R3_QUIT
                    LD   R6, TO_UPPERCASE  ; 加载32到R6
                    NOT  R3, R3            ; 取反R3准备加法
                    ADD  R3, R3, #1        ; 加1完成2's补码取反
                    ADD  R3, R3, R6        ; 加R6(32)完成减法,实现小写转大写
                NEXT_INSTRUCTION_QUIT
                ; 检查R4是否为小写,若是则转为大写
                LD    R6, MASK ;
                AND   R6, R4, R6     ; 用掩码判断是否为小写字母
                BRz   NOT_LOWERCASE_2_QUIT    ; 零标志表示不是小写字母
                ADD   R4, R4, #0         ; 根据R4设置条件码
                BRn   NOT_LOWERCASE_2_QUIT    ; 负标志表示不是小写字母(ASCII < 'a')
                BRzp  CASE_CHECK_R4      ; 零或正表示是小写字母
                NOT_LOWERCASE_2_QUIT
                BRnzp SKIP_CONVERSION_2_QUIT  ; 不是小写则跳过转换
            CASE_CHECK_R4_QUIT
                LD    R6, MASK
                AND   R6, R4, R6
                BRz CONVERT_R4_QUIT
                SKIP_CONVERSION_2_QUIT
                BRnzp NEXT_INSTRUCTION_FOR_R4_QUIT
                CONVERT_R4_QUIT
                    LD   R6, TO_UPPERCASE
                    NOT R4, R4
                    ADD R3, R3, #1
                    ADD   R4, R4, R6      ; 加二进制0010000将小写转大写
                    ; 继续处理R4
                    NEXT_INSTRUCTION_FOR_R4_QUIT
            ADD R6, R3, #0  ; 根据R3更新标志位
            BRz   CHECK_QUIT_END   ; 若R3为空,检查输入缓冲区是否结束
            ADD   R6, R4, #0         ; 根据R4更新标志位
            BRz   STRINGS_NOT_EQUAL_QUIT ; 若R4为空,说明不匹配
            ; 未遇到空字符,比较字符
            CHAR_EQUAL_QUIT
                ADD   R1, R1, #1         ; 移动到"QUIT"的下一个字符
                ADD   R2, R2, #1         ; 移动到输入缓冲区的下一个字符
                BRnzp CHECK_LOOP         ; 继续循环
            CONTINUE_COMPARE_QUIT
                ADD   R1, R1, #1       ; 移动到"QUIT"的下一个字符
                ADD   R2, R2, #1       ; 移动到输入缓冲区的下一个字符
                BRnzp CHECK_LOOP_QUIT       ; 循环返回
            CHECK_QUIT_END
                ADD   R6, R4, #0       ; 复制R4检查输入是否结束
                BRz   STRINGS_ARE_EQUAL_QUIT  ; 若R4为空,两个字符串都结束,即相等
                BRnzp STRINGS_NOT_EQUAL_QUIT  ; 若R4不为空,不匹配
            STRINGS_NOT_EQUAL_QUIT
                BRnzp STRING_COMPARE_QUIT_EXIT

            STRINGS_ARE_EQUAL_QUIT
                ; 设置"相等"标志,输入匹配"QUIT"(忽略大小写)
                AND   R5, R5, #0       ; 清除R5
                ADD   R5, R5, #1       ; 设置R5表示字符串相等
                BRzp EXIT
STRING_COMPARE_QUIT_EXIT

问题定位与修复方案

  1. 标签跳转错误
    CHAR_EQUAL_QUIT块末尾跳转到CHECK_LOOP,但正确的循环标签是CHECK_LOOP_QUIT,这会导致跳转到错误位置引发死循环,需修改为BRnzp CHECK_LOOP_QUIT。

  2. R4转换操作错误
    CONVERT_R4_QUIT块中错误执行了ADD R3, R3, #1,破坏了已处理的R3值,应改为ADD R4, R4, #1(配合前面的NOT R4, R4完成2's补码取反)。

  3. 缺失字符不等判断逻辑
    当前代码仅处理字符相等的情况,未判断字符不等时的分支。需在字符加载转换后添加比较逻辑:

    ; 比较转换后的R3和R4
    NOT R6, R4
    ADD R6, R6, #1
    ADD R6, R3, R6
    BRnp STRINGS_NOT_EQUAL_QUIT ; 字符不等则跳转到不匹配分支
    
  4. 标签定义不匹配
    跳转时使用CASE_CHECK_R4_QUIT,但标签定义为CASE_CHECK_R4,需统一标签后缀为_QUIT。

  5. 冗余检查逻辑简化
    CASE_CHECK_R3_QUIT中的重复掩码检查可移除,直接在确认是小写后执行转换,减少冗余操作。

内容的提问来源于stack exchange,提问作者Keoni Roring

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 18:03:10