如何用Irvine32在x86汇编中将表格内容写入文本文件?
搞定汇编代码中的学生成绩表格写入文件问题
嘿,咱们来解决你汇编代码里的文件写入难题!我看到你已经成功创建了lab4.txt,但核心问题是没把NameTable和GradeTable里的学生数据填充到写入用的buffer中,所以文件里是空的。下面一步步帮你修改实现:
1. 先理清现有代码的问题
你当前的WriteFile调用用了空的buffer,而且虽然文件操作的位置没问题,但缺少了最关键的一步——把表格里的结构化数据转成文件能识别的文本格式。我们需要先把每个学生的姓名和成绩拼接成一行行的文本,再写入文件。
2. 具体修改步骤
步骤1:添加填充buffer的代码块
在打印完控制台表格(P1循环结束后)、调用waitMsg之前,添加一段循环,把NameTable和GradeTable里的学生数据逐行复制到buffer中,还要加上分隔符和换行符:
; -------------------------- ; 填充buffer:将姓名和成绩转为文本行 ; -------------------------- mov esi, OFFSET NameTable ; 指向姓名表起始地址 mov edi, OFFSET buffer ; 指向buffer起始地址 mov cl, 0 ; 循环计数器,遍历每个学生 FillBufferLoop: cmp cl, NumInTable ; 检查是否遍历完所有已输入的学生 JE FillBufferDone ; 复制当前学生的姓名到buffer mov eax, FieldSizeName mul cl ; 计算当前姓名在NameTable中的偏移量 add esi, eax ; 让esi指向当前学生的姓名 mov ecx, FieldSizeName rep movsb ; 把姓名复制到buffer ; 添加空格分隔姓名和成绩(这里用5个空格,你可以调整数量) mov al, ' ' mov ecx, 5 rep stosb ; 复制当前学生的成绩到buffer mov esi, OFFSET GradeTable mov eax, FieldSizeGrade mul cl ; 计算当前成绩在GradeTable中的偏移量 add esi, eax ; 让esi指向当前学生的成绩 mov ecx, FieldSizeGrade rep movsb ; 把成绩复制到buffer ; 添加换行符(0Dh是回车,0Ah是换行,符合Windows文本格式) mov al, 0Dh stosb mov al, 0Ah stosb inc cl ; 切换到下一个学生 jmp FillBufferLoop FillBufferDone: ; 给buffer添加字符串结束符(可选,避免写入多余的垃圾数据) mov al, 0 stosb
步骤2:修正文件写入的参数
你原来的WriteFile用了stringLength(1000字节)作为写入长度,这会把buffer里未使用的部分也写入文件。我们应该计算实际填充的字节数:
; -------------------------- ; 文件操作:创建、写入、关闭 ; -------------------------- INVOKE CreateFile, OFFSET filename, GENERIC_WRITE, DO_NOT_SHARE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0 mov fileHandle, eax ; 计算实际要写入的字节数:当前buffer位置 - buffer起始地址 mov eax, edi sub eax, OFFSET buffer mov bytesWritten, eax INVOKE WriteFile, fileHandle, OFFSET buffer, eax, ; 用实际字节数代替原来的stringLength ADDR bytesWritten, 0 INVOKE CloseHandle, fileHandle
步骤3:调整代码位置
把上面的代码放到P1循环结束后、call waitMsg之前,替换掉你原来的空文件操作代码块就行。
3. 给新手的小优化建议
- 你的
InputBufferGrade定义成了20字节,但实际只需要1字节存A-F的成绩,可以改成InputBufferGrade BYTE ?,更高效。 - 读取成绩后,可以把小写字母转成大写,这样后续判断成绩时不用同时检查大小写,减少代码冗余:
call ReadString ; 把小写字母转成大写 cmp InputBufferGrade, 'a' JB SkipUpper cmp InputBufferGrade, 'z' JA SkipUpper sub InputBufferGrade, 20h ; ASCII中小写比大写多20h
SkipUpper:
这样后续只需要判断大写的A-F就够了,代码会简洁很多。 现在运行代码,打开`lab4.txt`就能看到格式化好的学生姓名和成绩列表啦! 内容的提问来源于stack exchange,提问作者Z.Cesare
相关产品推荐
相关产品推荐

