ASM入门问题:读取指定文件统计高频大写字母并显示其频次
解决汇编语言中大写字母频率统计及最高频字母显示问题
核心问题修复与实现
你已完成文件的打开和读取逻辑,缺失的是大写字母频率统计和最高频结果计算的核心逻辑。以下是完整的修改实现:
完整代码
bits 32 global start extern exit, fopen, fread, fclose, printf import exit msvcrt.dll import fopen msvcrt.dll import fread msvcrt.dll import fclose msvcrt.dll import printf msvcrt.dll segment data use32 class=data file_name db "ana.txt", 0 ; 目标读取文件名 access_mode db "r", 0 ; 文件只读模式 file_descriptor dd -1 ; 存储文件描述符 len equ 100 ; 单次最大读取字符数 text times (len+1) db 0 ; 缓存读取到的文本 freq times 26 db 0 ; 频率统计数组:索引0对应'A',25对应'Z' result_format db "出现频率最高的大写字母是: %c,出现次数: %d", 0 max_count db 0 ; 记录最大出现次数 max_char db 'A' ; 记录最高频字母 segment code use32 class=code start: ; 打开文件 push dword access_mode push dword file_name call [fopen] add esp, 4*2 mov [file_descriptor], eax cmp eax, 0 je final ; 读取文件内容 push dword [file_descriptor] push dword len push dword 1 push dword text call [fread] add esp, 4*4 ; 统计大写字母频率 mov ecx, eax ; ECX = 读取到的字符总数 mov esi, 0 jecxz find_max ; 无字符则直接进入结果查找 count_loop: mov al, [text + esi] ; 判断是否为大写字母 cmp al, 'A' jb next_char cmp al, 'Z' ja next_char ; 计算字母对应数组索引并计数 sub al, 'A' inc byte [freq + eax] next_char: inc esi loop count_loop ; 找出频率最高的字母及次数 find_max: mov ecx, 26 mov esi, 0 mov bl, [max_count] mov bh, [max_char] max_loop: mov al, [freq + esi] cmp al, bl jle continue ; 更新最大次数和对应字母 mov bl, al mov bh, 'A' add bh, esi continue: inc esi loop max_loop ; 保存结果 mov [max_count], bl mov [max_char], bh ; 打印结果 push dword [max_count] push dword [max_char] push dword result_format call [printf] add esp, 4*3 ; 关闭文件 push dword [file_descriptor] call [fclose] add esp, 4 final: push dword 0 call [exit]
关键逻辑说明
- 频率统计数组:用26字节的数组对应A-Z,通过
sub al, 'A'将大写字母转换为0-25的索引,直接对数组对应位置自增,实现高效计数。 - 最高频查找:遍历频率数组,实时记录当前最大次数和对应字母,通过
'A' + 索引将数组索引转换回原字符。 - 结果输出:利用
printf的%c和%d格式符,直接输出最高频字母及其出现次数。
内容的提问来源于stack exchange,提问作者Birou Rares
相关产品推荐
相关产品推荐

