我有一项任务要做。我会尽量解释清楚。
当您运行程序时,它要求输入(读取文件和写入文件)。
读取文件的行范围为1;999。每一行都有六列。每一列都用分号(;)分隔。
第一列和第二列包含范围1;20中的文本符号。
第三列-第五列包含整数- 100;100。
最后一列包含浮点数- 9.99;9.99。一个接一个有两个符号。
文件示例:
firstA;lB;lC;lD;lE;lF
A11;bas hello;0;0;5;1.15
B12; good day;-100;11;78;1.33任务:输出:只有第一列和第二列,它不包含数字和符号'B','C‘。
输出:
firstA,因为只有此列没有“B”、“C”和数字。
到目前为止,我已经写了程序,那只是扔掉数字和符号。我无法找到完整的任务的解决方案。
我的程序
%include 'yasmmac.inc'
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
org 100h
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
section .text
startas:
macPutString 'Reading file name:', crlf, '$' ;Input for reading file
mov al, 128
mov dx, readingFile
call procGetStr
macNewLine
macPutString 'Writing file name: ', crlf, '$' ;Input for writing file
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
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 .filter
macPutString 'Error while opening writing file', crlf, '$'
jmp .close
.filter:
mov [bp-4], bx
.whileNotTheEnd:
mov bx, [bp-2]
call procFGetChar
jnc .c1
macPutString 'Error while reading file', crlf, '$'
jmp .close
.c1:
cmp ax, 0 ; Checks if it is not the end of the file
jne .check
jmp .close ; If the end - close the file
.check:
mov al, cl
cmp al, ';' ; Checks if ';'
jne .c2
.c2:
cmp al, 30h ; Number checking
jge .c3
jmp .c4
.c3:
cmp al, 39h ; Number checking
jle .checkEnd
jmp .c4
.c4:
cmp al, 'B'
jne .c5
jmp .checkEnd
.c5:
cmp al, 'C'
jne .writing
jmp .checkEnd
.writing:
mov bx, [bp-4]
call procFPutChar
jnc .checkEnd
macPutString 'Error while writing file', crlf, '$'
jmp .close
.acheckEnd:
cmp ax, 0
jne .nextIteration
jmp .close
.nextIteration:
jmp .whileNotTheEnd
.close:
mov bx, [bp-4]
call procFClose
.closeReadingFile:
mov bx, [bp-2]
call procFClose
.end:
ret4
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
%include 'yasmlib.asm'
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
section .data
writingFile:
times 255 db 00
readingFile:
times 255 db 00
duomenys:
times 255 db 00
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
section .bss发布于 2022-11-10 23:25:08
网上找不到多少"yasmmac.inc“,但我相信我对这些procFGetChar和procFPutChar宏的理解不会太远.
如果不使用模块化方法,任务将显得过于复杂。您需要将更简单的子任务委托给单独的子例程。此外,从数据的来源抽象化也是有意义的。不要从文件中读取一个字符,并立即对其进行分类。不,从文件中提取完整的行,并从内存副本中处理所请求的字段。它将更容易,也不太容易出现与文件访问相关的错误。
.whileNotTheEnd:
; Fetch one line from the file
call .fgets ; -> DI (AX BX CL)
test di, di
jz .close ; Normal EOF
; Process fields 1 and 2 from the memory copy
mov si, Buffer
call .field ; -> SI (AX BX)
call .field ; -> SI (AX BX)
jmp .whileNotTheEnd
.close:
mov bx, [bp-4]
call procFClose
mov bx, [bp-2]
call procFClose文本文件中的每一行都有一个回车和linefeed对(13,10)。因此,找到10表示EOL。
从DOS接收AX=0意味着文件的结束。如果当缓冲区中还没有字符时,就会发生这种情况,它会发出正常的EOF信号。
; ----------------------
; IN (bp) OUT (di) MOD (ax,bx,cl)
.fgets:
mov bx, [bp-2] ; Handle
xor di, di ; Counts characters
.more:
call procFGetChar ; -> AX CL CF
jc .err1
test ax, ax ; EOF ?
jz .eof
mov [Buffer + di], cl
inc di
cmp cl, 10
jne .more
.ret:
ret
.eof:
test di, di ; If DI==0 then Normal EOF
jz .ret
.err1:
macPutString 'Error while reading file', crlf, '$'
pop ax ; (*) Forget about `call fgets`
jmp .close
; ----------------------字段子例程执行此程序的魔力,但即使它也会将字符的分类委托给进一步的子例程。这将提高可读性。根据经验,我尝试将每个子例程保持在一个屏幕(25行)的范围内。因为这段代码的结尾是SI指向当前字段,所以第二个字段很容易继续。
; ----------------------
; IN (si) OUT (si) MOD (ax,bx)
.field:
mov bx, si ; Remember the start of this field
.check:
lodsb
cmp al, ";"
je .write
call .test ; -> CF
jnc .check
.skip:
lodsb ; Skip remainder of this (bad) field
cmp al, ";"
jne .skip
ret
.write:
push si ; (1)
mov si, bx ; Send this field to file
lodsb
.w1:
call .fputc ; -> (AX BX)
lodsb
cmp al, ";"
jne .w1
pop si ; (1) SI points after the ";"
ret
; ----------------------
; IN (al) OUT (CF)
.test:
cmp al, "0"
jb .OK
cmp al, "9"
jbe .NOK
cmp al, "B"
je .NOK
cmp al, "C"
je .NOK
.OK:
clc
ret
.NOK:
stc
ret
; ----------------------
; IN (al,bp) OUT () MOD (ax,bx)
.fputc:
mov bx, [bp-4] ; Handle
call procFPutChar ; -> AX CF
jc .err2
test ax, ax
jz .err2
ret
.err2:
macPutString 'Error while writing file', crlf, '$'
pop ax ; (*) Forget about `call .fputc`
pop ax ; (*) Forget about `call .field`
jmp .close
; ----------------------(*) .fgets和.fputc中的错误退出需要平衡堆栈!他们需要“忘记”call__s是在jmp to .close能够安全通过之前制造的。
https://stackoverflow.com/questions/74372928
复制相似问题