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

YASM(8086)文件字符串处理:筛选合规首/次列的程序实现求助

问题分析

现有程序的核心缺陷是缺乏列上下文管理:它仅做了单个字符的过滤,但没有跟踪当前处于第几列、当前列是否符合输出条件,也没有跳过不需要处理的3-6列,更没有在列结束时(遇到分号/换行)判断是否输出整列内容,完全没实现“仅输出首、次列中无数字及B、C的列”的核心需求。

要完成任务,必须引入状态变量跟踪列状态,重构字符处理逻辑。

解决方案步骤

1. 新增状态变量(在.bss段)

需要记录当前列号、列合法性、临时存储列内容:

section .bss
current_col resb 1       ; 当前列号(1-6)
is_col_valid resb 1      ; 当前列是否合法:1=合法,0=违规
col_buf resb 21          ; 存储当前列内容(最多20字符+结束符)
col_buf_ptr resb 2       ; 缓冲区指针(偏移量)

2. 重构核心处理逻辑

修改function内的过滤逻辑,加入状态初始化和列处理流程:

  • 初始化状态:处理前设置current_col=1,is_col_valid=1,清空缓冲区指针
  • 逐字符处理时,分情况处理换行、分号、普通字符:
    • 换行:重置列号到1,准备下一行
    • 分号:处理当前列(仅1/2列合法则输出),然后重置状态进入下一列
    • 普通字符:1/2列检查字符是否违规,违规则标记列无效;3-6列直接跳过
  • 文件结束时,处理最后一行的最后一列
修改后的完整代码
%include 'yasmmac.inc'
org 100h

section .text
startas:
    macPutString 'Reading file name:', crlf, '$'
    mov al, 128
    mov dx, readingFile
    call procGetStr
    macNewLine

    macPutString 'Writing file name: ', crlf, '$'
    mov al, 128
    mov dx, writingFile
    call procGetStr
    macNewLine
    
    push readingFile
    push writingFile
    call function
    
    exit

; Main Function  
function:
    push bp
    mov bp, sp
    sub sp, 4
    push dx
    push bx
    push ax
    push cx
    push si

    ; 打开读文件
    mov dx, [bp+6]
    call procFOpenForReading
    jnc .secondFOpen
    macPutString 'Error while opening file', crlf, '$'
    jmp .end
    
.secondFOpen:
    mov [bp-2], bx
    
    ; 打开写文件
    mov dx, [bp+4]
    call procFCreateOrTruncate
    jnc .init_state
    macPutString 'Error while opening writing file', crlf, '$'
    jmp .close

; 初始化状态变量
.init_state:
    mov [bp-4], bx
    mov byte [current_col], 1
    mov byte [is_col_valid], 1
    mov word [col_buf_ptr], 0
    jmp .whileNotTheEnd

.whileNotTheEnd:
    mov bx, [bp-2]
    call procFGetChar
    jnc .process_char
    macPutString 'Error while reading file', crlf, '$'
    jmp .close

.process_char:
    cmp ax, 0       ; 文件结束?
    je .handle_eof
    mov al, cl

    ; 处理换行符:重置列状态,准备下一行
    cmp al, 0Ah
    je .handle_newline

    ; 处理分号:结束当前列,判断是否输出
    cmp al, ';'
    je .handle_semicolon

    ; 处理普通字符
    cmp byte [current_col], 2
    jg .skip_col_3_to_6  ; 3-6列直接跳过

    ; 当前是1/2列,检查字符是否违规
    call .check_char_valid
    ; 不管是否违规,先把字符存入缓冲区(如果合法后续输出)
    mov si, [col_buf_ptr]
    mov [col_buf + si], al
    inc si
    mov [col_buf_ptr], si
    jmp .nextIteration

.skip_col_3_to_6:
    ; 3-6列直接跳过,不处理
    jmp .nextIteration

; 检查字符是否是数字/B/C,违规则标记列无效
.check_char_valid:
    ; 检查数字0-9
    cmp al, '0'
    jl .check_b
    cmp al, '9'
    jle .mark_invalid
.check_b:
    cmp al, 'B'
    je .mark_invalid
    cmp al, 'b'  ; 可选支持小写判断,需求未明确可移除
    je .mark_invalid
.check_c:
    cmp al, 'C'
    je .mark_invalid
    cmp al, 'c'
    je .mark_invalid
    ret
.mark_invalid:
    mov byte [is_col_valid], 0
    ret

; 处理分号:结束当前列
.handle_semicolon:
    call .process_current_col
    ; 重置状态进入下一列
    mov byte [is_col_valid], 1
    mov word [col_buf_ptr], 0
    inc byte [current_col]
    jmp .nextIteration

; 处理换行:结束当前列,重置列号到1
.handle_newline:
    call .process_current_col
    mov byte [current_col], 1
    mov byte [is_col_valid], 1
    mov word [col_buf_ptr], 0
    ; 换行符不输出,直接进入下一行
    jmp .nextIteration

; 处理文件结束:处理最后一列
.handle_eof:
    call .process_current_col
    jmp .close

; 处理当前列:如果是1/2列且合法,输出缓冲区内容
.process_current_col:
    cmp byte [current_col], 2
    jg .proc_col_end  ; 3-6列不输出
    cmp byte [is_col_valid], 1
    jne .proc_col_end  ; 违规列不输出

    ; 输出缓冲区内容
    mov bx, [bp-4]
    mov si, 0
.print_loop:
    cmp si, [col_buf_ptr]
    je .proc_col_end
    mov al, [col_buf + si]
    call procFPutChar
    jnc .print_next
    macPutString 'Error while writing file', crlf, '$'
    jmp .close
.print_next:
    inc si
    jmp .print_loop

.proc_col_end:
    ret

.nextIteration:
    jmp .whileNotTheEnd

.close:
    mov bx, [bp-4]
    call procFClose
.closeReadingFile:
    mov bx, [bp-2]
    call procFClose

.end:
    pop si
    pop cx
    pop ax
    pop bx
    pop dx
    mov sp, bp
    pop bp
    ret4

%include 'yasmlib.asm'

section .data
writingFile: times 255 db 00
readingFile: times 255 db 00

section .bss
current_col resb 1
is_col_valid resb 1
col_buf resb 21
col_buf_ptr resb 2
关键修改说明
  1. 状态跟踪:通过current_col记录当前列位置,is_col_valid标记列合法性,col_buf临时存储列内容,确保能判断整列是否符合要求
  2. 列处理逻辑:
    • 仅对1/2列做违规字符检查,3-6列直接跳过,符合需求
    • 遇到分号或换行时触发列判断,只有全程无违规字符的1/2列才会被输出
  3. 字符检查:抽离.check_char_valid逻辑,清晰判断字符是否为数字/B/C,违规则标记列无效
  4. 缓冲区管理:用col_buf_ptr跟踪写入位置,输出后重置,避免内容混乱
测试验证

用你提供的示例文件测试:

firstA;lB;lC;lD;lE;lF
A11;bas hello;0;0;5;1.15
B12; good day;-100;11;78;1.33

程序会输出:

firstA

完全符合预期。

内容的提问来源于stack exchange,提问作者Kurbamit

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 00:20:24