MASM615基于Irvine32.inc实现未知元素数整数输入数组的声明问题
故障根源
- 你当前程序出现乱码、崩溃的核心原因是数组声明完全错误:
ArrayInteger DWORD ?仅申请了1个DWORD长度的独立内存单元,不是可存储多元素的连续数组。当输入超过1个整数时,后续写入操作会越界覆盖相邻内存,轻则读出无意义的乱码值,重则触发非法内存访问直接崩溃。 - 关于未知长度数组的实现:MASM的静态.data段在编译阶段就会固定内存布局,无法直接创建长度完全任意的动态数组。但课程作业场景下完全不需要使用复杂的堆内存动态申请,只要预先分配一块足够覆盖作业最大输入量的连续静态内存块,就能满足需求,还能规避绝大多数内存越界问题。
修正后的实现逻辑
- 调整.data段的声明,把单值内存改成可容纳多元素的数组,同时新增一个变量记录实际存入的元素个数:
; 最多支持100个整数输入,可根据作业要求调整DUP的数量 ArrayInteger DWORD 100 DUP(?) ArrayLen DWORD 0 ; 输入提示字符串,满足题目要求的交互提示 PromptStr BYTE "请输入整数,输入-1终止:",0 - 调整输入循环,在输入结束时记录实际存入的元素数量,为后续输出做准备:
INCLUDE Irvine32.inc .data ArrayInteger DWORD 100 DUP(?) ArrayLen DWORD 0 PromptStr BYTE "请输入整数,输入-1终止:",0 .code main PROC mov esi, 0 ; esi作为数组的元素索引,从0开始计数 InputLoop: mov edx, OFFSET PromptStr call WriteString ; 打印输入提示 call ReadInt ; 读入用户输入的整数到eax cmp eax, -1 ; 判断是否为终止标记-1 je EndInput ; 遇到-1就跳出输入流程 ; 合法输入写入数组:因为数组元素是DWORD(4字节),所以用esi*4做偏移 mov ArrayInteger[esi * 4], eax inc esi ; 索引后移,存下一个数 jmp InputLoop EndInput: mov ArrayLen, esi ; 把实际存储的元素数量保存到变量中,供输出环节使用 ; 参考输出逻辑:按照实际记录的元素个数遍历数组,避免读到未初始化的内存 mov ecx, ArrayLen mov esi, 0 OutputLoop: mov eax, ArrayInteger[esi * 4] call WriteInt ; 调用Irvine库的整数输出函数 call Crlf ; 输出换行 inc esi loop OutputLoop exit main ENDP END main
常见避坑点
- 预分配数组的大小要留足够富余,比如作业要求最多输入50个整数,就开60个元素的空间,避免用户输入超量时出现越界崩溃。
- 输出时必须用实际记录的元素数量作为循环上限,不要遍历整个预分配的数组空间,否则会把未使用的空白内存中的随机值打印出来,就是之前遇到的乱码问题。
- 原代码中悬空的
L2标签没有实际逻辑,可以直接删除,不影响程序运行。
内容的提问来源于stack exchange,提问作者Astra99
相关产品推荐
相关产品推荐

