assembly - 读取输入文件并创建多个输出文件来存储数据
问题描述
我对汇编语言相当陌生,我的任务要求我将文件名和数字作为输入(例如:data.txt 100)并将该文件分成多个文件,每个文件存储 100 个字符(所以如果我的 data.txt 有520 个字符,它将创建 6 个新文件,名称为 data1 data2 ... 第 6 个文件将有 20 个字符。
目前我有一个应用程序,它采用输入文件的名称,并在循环时创建新文件(询问辅助文件的名称,直到循环结束)
我面临的问题是我无法使文件自动更改名称(data1 data2 data3 ...)我也无法使辅助输入成为要读取的字符数量(因此它当前设置为1)
任何类型的智慧都受到高度赞赏
我的代码:
.model small
.stack 100h
.data
handle dw ?
handle2 dw ?
filename db 26 ;MAX NUMBER OF CHARACTERS ALLOWED (25).
db ? ;LENGTH (NUMBER OF CHARACTERS ENTERED BY USER).
db 26 dup(0) ;CHARACTERS ENTERED BY USER. END WITH CHR(13).
filename2 db 26 ;MAX NUMBER OF CHARACTERS ALLOWED (25).
db ? ;LENGTH (NUMBER OF CHARACTERS ENTERED BY USER).
db 26 dup(0) ;CHARACTERS ENTERED BY USER. END WITH CHR(13).
prompt1 db 13,10,"ENTER FILE NAME HERE: $"
prompt2 db 13,10,"ENTER A SECONDARY FILE NAME: $"
mess1 db ' I WIN! $'
buf db ?
.code
main:
mov ax, @data ; set up addressability of data
mov ds, ax
;DISPLAY MESSAGE.
lea dx, prompt1 ; load and print the string PROMPT
mov ah, 9
int 21h
;CAPTURE FILENAME FROM KEYBOARD.
mov ah, 0Ah
mov dx, offset filename ;THIS VARIABLE REQUIRES THE 3-DB FORMAT.
int 21h
;CAPTURED STRING ENDS WITH CHR(13), BUT TO CREATE FILE WE NEED
;THE FILENAME TO END WITH CHR(0), SO LET'S CHANGE IT.
mov si, offset filename + 1 ;NUMBER OF CHARACTERS ENTERED.
mov cl, [ si ] ;MOVE LENGTH TO CL.
mov ch, 0 ;CLEAR CH TO USE CX.
inc cx ;TO REACH CHR(13).
add si, cx ;NOW SI POINTS TO CHR(13).
mov al, 0
mov [ si ], al ;REPLACE CHR(13) BY 0.
;OPEN FILE TO READ FROM IT.
mov ah, 3DH
mov al, 0 ;READ MODE.
mov dx, offset filename + 2
int 21h
mov handle, ax ; save file handle
f1:
;DISPLAY MESSAGE FOR SECOND FILE.
lea dx, prompt2 ; load and print the string PROMPT
mov ah, 9
int 21h
;CAPTURE FILENAME FROM KEYBOARD.
mov ah, 0Ah
mov dx, offset filename2 ;THIS VARIABLE REQUIRES THE 3-DB FORMAT.
int 21h
;CAPTURED STRING ENDS WITH CHR(13), BUT TO CREATE FILE WE NEED
;THE FILENAME TO END WITH CHR(0), SO LET'S CHANGE IT.
mov si, offset filename2 + 1 ;NUMBER OF CHARACTERS ENTERED.
mov cl, [ si ] ;MOVE LENGTH TO CL.
mov ch, 0 ;CLEAR CH TO USE CX.
inc cx ;TO REACH CHR(13).
add si, cx ;NOW SI POINTS TO CHR(13).
mov al, 0
mov [ si ], al ;REPLACE CHR(13) BY 0.
;CREATE FILE.
mov ah, 3ch ; dos service to create file
mov cx, 0 ;READ/WRITE MODE.
mov dx, offset filename2 + 2 ;CHARACTERS START AT BYTE 2.
int 21h
mov handle2, ax ; save file handle
;READ ALL BYTES FROM FIRST FILE AND WRITE THEM TO SECOND FILE.
reading:
;READ ONE BYTE.
mov ah, 3FH
mov bx, handle
mov cx, 1 ;HOW MANY BYTES TO READ.
mov dx, offset buf ;THE BYTE WILL BE STORED HERE.
int 21h ;NUMBER OF BYTES READ RETURNS IN AX.
;CHECK EOF (END OF FILE).
cmp ax, 0 ;IF AX == 0 THEN EOF.
je eof
;WRITE BYTE TO THE SECOND FILE.
mov ah, 40h ; write to
mov bx, handle2 ; file
mov dx, offset buf ; where to find data to write
mov cx, 1 ;LENGTH OF STRING IN CX.
int 21h
jmp f1 ;REPEAT PROCESS.
eof:
;CLOSE FILES.
mov ah, 3Eh ; close file
mov bx, handle ; which file
int 21h
mov ah, 3Eh ; close file
mov bx, handle2 ; which file
int 21h
mov ah, 4ch
int 21h
end main
解决方案
.model small
.stack 100h
.data
handle dw ?
handle2 dw ?
filename db 26 ;MAX NUMBER OF CHARACTERS ALLOWED (25).
db ? ;LENGTH (NUMBER OF CHARACTERS ENTERED BY USER).
db 26 dup(0) ;CHARACTERS ENTERED BY USER. END WITH CHR(13).
filename2 db 26 ;MAX NUMBER OF CHARACTERS ALLOWED (25).
db ? ;LENGTH (NUMBER OF CHARACTERS ENTERED BY USER).
db 26 dup(0) ;CHARACTERS ENTERED BY USER. END WITH CHR(13).
prompt1 db 13,10,"ENTER FILE NAME HERE: $"
prompt2 db 13,10,"ENTER A SECONDARY FILE NAME: $"
prompt3 db 13,10,"ENTER LETTER COUNT: $"
mess1 db ' I WIN! $'
buf db ?
input db 30 dup ('$')
n dw ?
count dw ?
count2 dw ?
output db 30 dup ('$')
msj db 13,10,'The number is = $'
.code
main:
mov ax, @data ; set up addressability of data
mov ds, ax
;DISPLAY MESSAGE.
lea dx, prompt1 ; load and print the string PROMPT
mov ah, 9
int 21h
;CAPTURE FILENAME FROM KEYBOARD.
mov ah, 0Ah
mov dx, offset filename ;THIS VARIABLE REQUIRES THE 3-DB FORMAT.
int 21h
;CAPTURED STRING ENDS WITH CHR(13), BUT TO CREATE FILE WE NEED
;THE FILENAME TO END WITH CHR(0), SO LET'S CHANGE IT.
mov si, offset filename + 1 ;NUMBER OF CHARACTERS ENTERED.
mov cl, [ si ] ;MOVE LENGTH TO CL.
mov ch, 0 ;CLEAR CH TO USE CX.
inc cx ;TO REACH CHR(13).
add si, cx ;NOW SI POINTS TO CHR(13).
mov al, 0
mov [ si ], al ;REPLACE CHR(13) BY 0.
;OPEN FILE TO READ FROM IT.
mov ah, 3DH
mov al, 0 ;READ MODE.
mov dx, offset filename + 2
int 21h
mov handle, ax ; save file handle
jmp w1
f1:
;READ ALL BYTES FROM FIRST FILE AND WRITE THEM TO SECOND FILE.
mov count2, 0
reading:
mov ah, 3FH
mov bx, handle
xor dx, dx
mov dx, offset buf
mov cx, 1 ;HOW MANY BYTES TO READ.
mov dx, offset buf ;THE BYTE WILL BE STORED HERE.
int 21h ;NUMBER OF BYTES READ RETURNS IN AX.
;CHECK EOF (END OF FILE).
;push cx
cmp ax, 0 ;IF AX == 0 THEN EOF.
je eof
cmp count2, 0
jne writ
;DISPLAY MESSAGE FOR SECOND FILE.
lea dx, prompt2 ; load and print the string PROMPT
mov ah, 9
int 21h
;CAPTURE FILENAME FROM KEYBOARD.
mov ah, 0Ah
mov dx, offset filename2 ;THIS VARIABLE REQUIRES THE 3-DB FORMAT.
int 21h
;CAPTURED STRING ENDS WITH CHR(13), BUT TO CREATE FILE WE NEED
;THE FILENAME TO END WITH CHR(0), SO LET'S CHANGE IT.
mov si, offset filename2 + 1 ;NUMBER OF CHARACTERS ENTERED.
mov cl, [ si ] ;MOVE LENGTH TO CL.
mov ch, 0 ;CLEAR CH TO USE CX.
inc cx ;TO REACH CHR(13).
add si, cx ;NOW SI POINTS TO CHR(13).
mov al, 0
mov [ si ], al ;REPLACE CHR(13) BY 0.
;CREATE FILE.
mov ah, 3ch ; dos service to create file
mov cx, 0 ;READ/WRITE MODE.
mov dx, offset filename2 + 2 ;CHARACTERS START AT BYTE 2.
int 21h
mov handle2, ax ; save file handle
writ:
inc count2
;WRITE BYTE TO THE SECOND FILE.
mov ah, 40h ; write to
mov bx, handle2 ; file
mov dx, offset buf ; where to find data to write
mov cx, 1 ;LENGTH OF STRING IN CX.
int 21h
mov cx, count
cmp cx, count2
je f1
;cmp ax, count
jmp reading ;REPEAT PROCESS.
eof:
;CLOSE FILES.
mov ah, 3Eh ; close file
mov bx, handle ; which file
int 21h
mov ah, 3Eh ; close file
mov bx, handle2 ; which file
int 21h
mov ah, 4ch
int 21h
;WORK WITH NUMBER
w1:
;DISPLAY MESSAGE.
mov dx , offset prompt3
mov ah, 9
int 21h
;CAPTURE NUMBER CHAR BY CHAR. NOTICE CHR(13) WILL BE
;STORED IN STRING AND COUNTED.
mov bx , offset input
mov count , 0
l1:
mov ah , 1
int 21h ;CAPTURE ONE CHAR FROM KEYBOARD.
mov [bx] , al ;STORE CHAR IN STRING.
inc bx
inc count
cmp al , 13
jne l1 ;IF CHAR IS NOT "ENTER", REPEAT.
dec count ;NECESSARY BECAUSE CHR(13) WAS COUNTED.
;CONVERT STRING TO NUMBER.
mov bx , offset input ;BX POINTS TO THE FIRST CHAR.
add bx, count ;NOW BX POINTS ONE CHAR AFTER THE LAST ONE.
mov bp, 0 ;BP WILL BE THE NUMBER CONVERTED FROM STRING.
mov cx, 0 ;PROCESS STARTS WITH 10^0.
l2:
;GET CURRENT POWER OF 10.
cmp cx, 0
je first_time ;FIRST TIME IS 1, BECAUSE 10^0 = 1.
mov ax, 10
mul cx ;CX * 10. NEXT TIME=100, NEXT TIME=1000...
mov cx, ax ;CX == 10^CX.
jmp l22 ;SKIP THE "FIRST TIME" BLOCK.
first_time:
mov cx, 1 ;FIRST TIME 10^0 = 1.
l22:
;CONVERT CURRENT CHAR TO NUMBER.
dec bx ;BX POINTS TO CURRENT CHAR.
mov al , [bx] ;AL = CURRENT CHAR.
sub al , 48 ;CONVERT CHAR TO NUMBER.
;MULTIPLY CURRENT NUMBER BY CURRENT POWER OF 10.
mov ah, 0 ;CLEAR AH TO USE AX.
mul cx ;AX * CX = DX:AX. LET'S IGNORE DX.
add bp , ax ;STORE RESULT IN BP.
;CHECK IF THERE ARE MORE CHARS.
dec count
cmp count , 0
jne l2
push bp
pop count
jmp f1
end main
这是有类似问题的人的答案,这是我找到的解决方案。应用程序将根据所选大小将文件拆分为多个单独的文件。到目前为止,它并不是最有效的,因为每个字母都是单独读取的,但是它完成了这项工作,它成功地分割了一个图片文件,并使用 Windows 命令我设法将它恢复为原始图片。
第一个输入需要您要拆分的文件的名称(例如 data.txt 或 picture.png)第二个是您希望在单个文件中的字符数量(最多 35000 个左右,在拆分文件时要小心10000 个字符分成小块可能会创建数百个文件)第三到 x 输入是新创建的文件名(例如 data1 , data2.txt , data3.png ......等它会询问文件名,直到第一个文件到达末尾,因此将 100 个字母文件除以 1 个字符将要求您提供 100 个名称作为输入)。
祝你好运,编程愉快:)
推荐阅读
- android - 垂直握持设备时的方向
- javascript - reactjs 将数据从 span 标签传递到另一个组件
- ruby-on-rails - 如何将多个复选框的值保存在单个列中
- javascript - HTML Canvas 不显示图像
- python - 如何使用 filter() 技术从字符串生成整数?
- python - 与他人共享 jupyter notebook 脚本以便能够在他们的 Windows 计算机上运行它的最佳方式是什么?
- c# - 有没有办法避免使用 EF Core 查询进行 foreach
- mysql - 全文搜索未找到某些特定词,这些词未包含在停用词中
- java - 如何检查java字符串是否包含数字和字母?
- python - Python套接字:接收帧队列管理