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

字符串中a/b/c大小写字母计数的汇编代码技术咨询

x86汇编实现a/b/c大小写字母统计的代码补全与解析

我来帮你完善并解析这段用于统计字符串中a、b、c大小写字母出现次数的x86汇编代码,先看修正补全后的完整代码:

.data
str: .ascii "assembly language is fun.\0"  # 修正:字符串结束符应为\0而非./0
.equ len, (. - str)                        # 计算字符串总字节长度
counta: .int 0                             # 小写a的计数变量
countb: .int 0                             # 小写b的计数变量
countc: .int 0                             # 小写c的计数变量
countA: .int 0                             # 大写A的计数变量
countB: .int 0                             # 大写B的计数变量
countC: .int 0                             # 大写C的计数变量
lowera: .ascii "a"
lowerb: .ascii "b"
lowerc: .ascii "c"
uppera: .ascii "A"
upperb: .ascii "B"
upperc: .ascii "C"

.text
.globl _start
_start:
    lea str, %esi               # 将字符串首地址加载到esi,作为遍历指针
    mov $len, %ecx              # 用ecx存储字符串长度,作为循环计数器(修复原代码寄存器冲突问题)
    
    # 预加载各个目标字母到寄存器,减少内存访问次数
    mov lowera, %al
    mov lowerb, %bl
    mov lowerc, %cl
    mov uppera, %dl
    mov upperb, %ah
    mov upperc, %bh

forloop:
    cmpb (%esi), %al            # 比较当前字符是否为小写a
    je doescounta
    cmpb (%esi), %bl            # 比较当前字符是否为小写b
    je doescountb
    cmpb (%esi), %cl            # 比较当前字符是否为小写c
    je doescountc
    cmpb (%esi), %dl            # 比较当前字符是否为大写A
    je doescountA
    cmpb (%esi), %ah            # 比较当前字符是否为大写B
    je doescountB
    cmpb (%esi), %bh            # 比较当前字符是否为大写C
    je doescountC
    jmp next                    # 不匹配任何目标字符,直接跳转到下一个字符

doescounta:
    incl counta                 # 小写a计数+1
    jmp next
doescountb:
    incl countb                 # 小写b计数+1
    jmp next
doescountc:
    incl countc                 # 小写c计数+1
    jmp next
doescountA:
    incl countA                 # 大写A计数+1
    jmp next
doescountB:
    incl countB                 # 大写B计数+1
    jmp next
doescountC:
    incl countC                 # 大写C计数+1
    jmp next

next:
    inc %esi                    # 指针向后移动一位,指向下一个字符
    loop forloop                # ecx自动减1,若不为0则跳回forloop继续循环

    # Linux系统调用:程序正常退出
    mov $1, %eax                # 系统调用号:exit
    mov $0, %ebx                # 退出码:0
    int $0x80                   # 触发系统调用

关键细节说明

  • 数据段修正:原代码中字符串结束符写错为./0,正确的ASCII字符串终止符应为\0,否则程序会读取内存中后续的垃圾数据,导致统计结果错误。
  • 寄存器冲突修复:原代码先将%ecx清零,随后又把小写c的ASCII值存入%cl(%ecx的低8位),直接破坏了循环计数器。这里调整为先把字符串长度存入%ecx,再利用loop指令自动管理循环计数(loop会自动将%ecx减1,若结果不为0则跳转回循环入口)。
  • 字符比较逻辑:通过cmpb指令逐字节对比当前指针指向的字符与目标字母,匹配则跳转到对应计数标签执行自增操作,不匹配则直接移动指针继续遍历。
  • 程序退出逻辑:使用Linux系统调用exit终止程序,确保执行完成后正确释放资源。

内容的提问来源于stack exchange,提问作者Cody Yan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:26:23