字符串中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
相关产品推荐
相关产品推荐

