You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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
相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:42:24