MASM汇编数组元素出现次数统计:显示计数功能问题求助
MASM汇编计数与显示功能问题修正
任务回顾
生成counts数组,统计randArray(随机数组)中[LO, HI](默认15-50)范围内每个值的出现次数,未出现的值记为0。例如LO=15时,counts[0]对应15的出现次数,counts[14]对应29的出现次数。
代码问题分析
- counts数组未初始化:统计前未将counts数组置0,未出现的值会保留内存随机值,不符合要求。
- 未处理超出范围的元素:randArray中若存在小于LO或大于HI的值,会导致counts数组越界访问,破坏内存。
- displayCounts循环次数错误:硬编码循环次数为20(randArray大小),但counts数组实际大小应为
HI-LO+1=36,导致显示不全或多余垃圾数据。 - 寄存器未妥善保存:未保留edi、esi、ebx等非易失性寄存器,可能破坏调用者上下文。
修正后的代码
常量补充
;constants: HI = 50 LO = 15 ARRAYSIZE = 20 LINE_LIMIT = 5 COUNTS_SIZE = HI - LO + 1 ; 新增:计算counts数组实际大小
countList PROC(修正版)
countList PROC push ebp mov ebp, esp push edi push esi push ebx ; 1. 初始化counts数组为0 mov esi, [ebp+8] ; counts数组基地址 mov ecx, COUNTS_SIZE mov eax, 0 initLoop: mov [esi], eax add esi, 4 loop initLoop ; 2. 统计randArray中符合范围的元素 mov edx, 1 mov ecx, ARRAYSIZE mov edi, [ebp+12] ; randArray基地址 countLoop: mov ebx, [edi] ; 检查元素是否在[LO, HI]范围内 cmp ebx, LO jl skipCount ; 小于LO,跳过计数 cmp ebx, HI jg skipCount ; 大于HI,跳过计数 ; 计算索引并累加计数 sub ebx, LO mov esi, [ebp+8] add esi, ebx*4 ; 每个元素占4字节,索引需乘4 add [esi], edx skipCount: add edi, 4 loop countLoop pop ebx pop esi pop edi pop ebp ret 8 countList ENDP
displayCounts PROC(修正版)
displayCounts PROC push ebp mov ebp, esp push esi push ebx mov esi, [ebp+12] ; counts数组基地址 mov ecx, COUNTS_SIZE ; 使用正确的数组大小 mov edx, [ebp+8] call CrLf call WriteString call CrLf mov ebx, 0 ; 每行元素计数器 displayElement: mov eax, [esi] call WriteDec mov edx, OFFSET twoSpace call WriteString inc ebx ; 检查是否达到每行元素限制 cmp ebx, LINE_LIMIT jl skipNextLine call CrLf mov ebx, 0 ; 重置行计数器 skipNextLine: add esi, 4 ; 移动到下一个4字节元素 loop displayElement pop ebx pop esi pop ebp ret 8 displayCounts ENDP
关键修正说明
- 新增
COUNTS_SIZE常量,避免硬编码数组大小,提升代码可维护性。 - 增加counts数组初始化步骤,确保未出现的值显示为0。
- 添加范围检查逻辑,防止越界访问内存。
- 修正displayCounts的循环次数为counts数组实际大小。
- 保存/恢复非易失性寄存器,符合MASM调用约定。
内容的提问来源于stack exchange,提问作者dami1025
相关产品推荐
相关产品推荐

