顶着感冒+两星期狂肝的过劳敲完了这东西,难度不大但是挺恶心的。
禁止搬运,禁止抄袭,看到了就看到了不要进行传播,你的传播会为我带来麻烦,以上
计算机原理与应用大作业 Ⅰ
程序设计思路
根据题意,程序需要完成的功能分为以下内容
- 输入文件名,将文件内容读入存储区
- 将文件内容转变成大写,然后输出
- 遍历文件,统计每个字母的个数
- 按照规则进行加密
- 将结果输出到到文件
为了能够有序的完成以上功能,我选择将这些功能封装成子程序,通过主程序的调用来完成完整的功能。
在完成这些功能时,我使用了一些在C语言程序设计或者是数据结构与算法中所使用过的技巧。
在进行文件内容转变成大写时,我对整个文件进行遍历,判断字符是否为小写字母,如果是则将其转变为大写字母
在统计字母个数时,我的方法是进行双重循环遍历的方式来进行统计。针对从A-Z的26个字母,进行26次对整个文章的遍历查找,统计每一次查找中对应的字符个数进行累加,便能够得到统计结果。
此外在统计时,我通过遍历统计结果,查找一个有两个数比其大的数据来找到Key,通过这种方式避免了对整个数据进行排序,减小了工作量。
在进行加密的时候,我在存储区中设计了一张加密表,通过计算偏移量然后再查表得方式得到加密得结果,避免了复杂的判断结构。
流程图
程序代码
完整代码:
DATA SEGMENT
INPUTBUF DB 10
DB ?
DB 10 DUP('$')
FILENAME DB 10 DUP('0')
OUTPUTFILENAME DB 10 DUP('$')
HANDLE DW ?
ARTICLE DB 300H DUP('$')
CNTBUF DB 'A',0,0,'B',0,0,'C',0,0,'D',0,0,'E',0,0,'F',0,0,'G',0,0,'H',0,0,'I',0,0,'J',0,0,'K',0,0,'L',0,0,'M',0,0,'N',0,0,'O',0,0,'P',0,0,'Q',0,0,'R',0,0,'S',0,0,'T',0,0,'U',0,0,'V',0,0,'W',0,0,'X',0,0,'Y',0,0,'Z',0,0,'$'
KEY DB 0
NEWLINE DB 0AH,0DH,'$'
ERRORBUF DB 0AH,0DH,'error','$'
NUMTABLE DB '7','5','9','1','3','6','8','0','2','4'
ARITCLELEN DW 0
CIPHERFILENAME DB 'cipher.txt',0
DATA ENDS
STACKS SEGMENT STACK
DW 100 DUP(0)
STACKS ENDS
CODE SEGMENT
ASSUME DS:DATA,CS:CODE,SS:STACKS
START:
MOV AX,DATA
MOV DS,AX
MOV DX,STACKS
MOV SS,DX
;输入文件名
CALL INPUT
;打开文件,将所有英文字母变成大写,输出
CALL CAPITALOUTPUT
;统计频率
CALL CNTOUTPUT
;加密
CALL ENCRYPTION
;存储
CALL SAVE
MOV AH,4CH
INT 21H
;子程序段
INPUT PROC
PUSH SI
PUSH DI
PUSH DX
PUSH AX
PUSH CX
PUSH BX
;输入文件名
MOV AH,0AH
LEA DX,INPUTBUF
INT 21H
MOV CH,00H
MOV SI,OFFSET INPUTBUF
INC SI
MOV CL,[SI]
INC SI
MOV DI,OFFSET FILENAME
A:
MOV AL,[SI]
MOV [DI],AL
INC SI
INC DI
LOOP A
MOV DX,OFFSET FILENAME
;以只读打开文件
MOV AL,00H
MOV AH,3DH
INT 21H
JC ERROR
;将文件内容读入存储区
MOV HANDLE,AX
MOV BX,AX
MOV CX,999
MOV DX,OFFSET ARTICLE
MOV AH,3FH
INT 21H
JC ERROR
MOV ARITCLELEN,AX
JMP INPUTDONE
ERROR:
MOV DX,OFFSET ERRORBUF
MOV AH,09H
INT 21H
INPUTDONE:
POP BX
POP CX
POP AX
POP DX
POP DI
POP SI
RET
INPUT ENDP
;全部转换成大写数字进行输出
CAPITALOUTPUT PROC
PUSH SI
PUSH DI
PUSH DX
PUSH AX
PUSH CX
PUSH BX
MOV CX,ARITCLELEN
MOV SI,OFFSET ARTICLE
;检查是否是小写字母
B:
MOV AL,[SI]
CMP AL,'a'
JAE CMPZ
INC SI
LOOP B
JMP CAPITALDONE
CMPZ:
CMP AL,'z'
JBE LOWERCASE
INC SI
LOOP B
JMP CAPITALDONE
LOWERCASE:
SUB AL,32
MOV [SI],AL
INC SI
LOOP B
CAPITALDONE:
;输出
MOV DX,OFFSET NEWLINE
MOV AH,09H
INT 21H
MOV DX,OFFSET ARTICLE
MOV AH,09H
INT 21H
POP BX
POP CX
POP AX
POP DX
POP DI
POP SI
RET
CAPITALOUTPUT ENDP
;统计词频
CNTOUTPUT PROC
PUSH SI
PUSH DI
PUSH DX
PUSH AX
PUSH CX
PUSH BX
MOV SI,OFFSET ARTICLE
MOV DI,OFFSET CNTBUF
INC DI
MOV CX,ARITCLELEN
MOV BH,00
MOV BL,26
MOV AH,00
MOV DL,00
;双重循环统计词频
C:
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH SI
PUSH DI
D:
MOV AL,[SI]
SUB AL,'A'
CMP AL,AH
JE FOUND
INC SI
JMP NOTFOUND
FOUND:
MOV AL,[DI]
INC AL
DAA
MOV [DI],AL
INC SI
NOTFOUND:
LOOP D
POP DI
POP SI
POP DX
POP CX
POP BX
POP AX
INC AH
ADD DI,03H
DEC BL
JNZ C
;找出key,我想到一个很暴力的算法,用一个数去遍历数组,找比自己大的数统计个数
MOV DI,OFFSET CNTBUF
MOV SI,OFFSET CNTBUF
ADD DI,01H
MOV CH,00H
MOV CL,26
MOV AH,26
;外层循环遍历整个数组
LKEY:
MOV AL,[DI]
MOV BL,[SI]
MOV BH,00H
PUSH BX
PUSH AX
PUSH SI
PUSH DI
;内层循环同样遍历整个数组
MOV DI,OFFSET CNTBUF
INC DI
CMPKEY:
MOV BL,[DI]
CMP AL,BL
JB JUDGE
BREAK:
ADD DI,03H
DEC AH
JNZ CMPKEY
CMP BH,2
JE KEYGET
MOV BH,0
JMP KEYDONE
JUDGE:
INC BH
JMP BREAK
KEYGET:
MOV AL,[SI]
SUB AL,'A'
MOV DI,OFFSET KEY
MOV [DI],AL
KEYDONE:
POP DI
POP SI
POP AX
POP BX
ADD DI,03H
ADD SI,03H
LOOP LKEY
;把统计到的十进制数转换成字符
MOV DI,OFFSET CNTBUF
INC DI
MOV SI,OFFSET CNTBUF
INC SI
MOV BH,00
MOV BL,26
MOV CL,4
E:
MOV AL,[DI]
MOV DL,AL
AND AL,0F0H
ROL AL,CL
ADD AL,'0'
MOV [SI],AL
INC SI
MOV AL,DL
AND AL,0FH
ADD AL,'0'
MOV [SI],AL
ADD SI,02H
ADD DI,03H
DEC BL
JNZ E
;输出
MOV DX,OFFSET NEWLINE
MOV AH,09H
INT 21H
MOV DX,OFFSET NEWLINE
MOV AH,09H
INT 21H
MOV DX,OFFSET CNTBUF
MOV AH,09H
INT 21H
POP BX
POP CX
POP AX
POP DX
POP DI
POP SI
RET
CNTOUTPUT ENDP
;进行加密
ENCRYPTION PROC
PUSH SI
PUSH DI
PUSH DX
PUSH AX
PUSH CX
PUSH BX
MOV SI,OFFSET ARTICLE
MOV CX,ARITCLELEN
MOV DI,OFFSET NUMTABLE
MOV AH,00H
F:
MOV AL,[SI]
;判断是字母还是数字
CMP AL,'0'
JAE CMPNINE
CAPITALJUDGE:
CMP AL,'A'
JAE ENCRYPTIONCMPZ
CONTINUE:
INC SI
LOOP F
JMP ENCRYPTIONDONE
CMPNINE:
CMP AL,'9'
JBE NUMENCRYPTION
JMP CAPITALJUDGE
ENCRYPTIONCMPZ:
CMP AL,'Z'
JBE LETTERENCRYPTION
JMP CONTINUE
;数字加密
NUMENCRYPTION:
PUSH DI
PUSH AX
SUB AL,'0'
ADD DI,AX
MOV AL,[DI]
MOV [SI],AL
POP AX
POP DI
JMP CONTINUE
;字母加密
LETTERENCRYPTION:
PUSH AX
PUSH DI
PUSH BX
SUB AL,'A'
MOV DI,OFFSET KEY
MOV AH,[DI]
ADD AL,AH
MOV AH,00H
MOV BL,26
DIV BL
MOV AL,AH
ADD AL,41H
MOV [SI],AL
POP DI
POP BX
POP AX
JMP CONTINUE
ENCRYPTIONDONE:
MOV DX,OFFSET NEWLINE
MOV AH,09H
INT 21H
MOV DX,OFFSET NEWLINE
MOV AH,09H
INT 21H
MOV DX,OFFSET ARTICLE
MOV AH,09H
INT 21H
POP BX
POP CX
POP AX
POP DX
POP DI
POP SI
RET
ENCRYPTION ENDP
;文件存储
SAVE PROC
PUSH SI
PUSH DI
PUSH DX
PUSH AX
PUSH CX
PUSH BX
;创建文件
MOV DX,OFFSET CIPHERFILENAME
MOV CX,00H
MOV AH,3CH
INT 21H
JC OUTPUTERROR
;写入数据
MOV HANDLE,AX
MOV BX,AX
MOV CX,ARITCLELEN
MOV DX,OFFSET ARTICLE
MOV AH,40H
INT 21H
JC OUTPUTERROR
;关闭文件
MOV BX,HANDLE
MOV AH,3EH
INT 21H
JC OUTPUTERROR
JMP OUTPUTDONE
OUTPUTERROR:
MOV AH,09H
MOV DX,OFFSET NEWLINE
INT 21H
MOV AH,09H
MOV DX,OFFSET ERRORBUF
INT 21H
OUTPUTDONE:
POP BX
POP CX
POP AX
POP DX
POP DI
POP SI
RET
SAVE ENDP
CODE ENDS
END START
主程序段:
MOV AX,DATA
MOV DS,AX
MOV DX,STACKS
MOV SS,DX
;输入文件名
CALL INPUT
;打开文件,将所有英文字母变成大写,输出
CALL CAPITALOUTPUT
;统计频率
CALL CNTOUTPUT
;加密
CALL ENCRYPTION
;存储
CALL SAVE
MOV AH,4CH
INT 21H
输入文件名子函数:
INPUT PROC
PUSH SI
PUSH DI
PUSH DX
PUSH AX
PUSH CX
PUSH BX
;输入文件名
MOV AH,0AH
LEA DX,INPUTBUF
INT 21H
MOV CH,00H
MOV SI,OFFSET INPUTBUF
INC SI
MOV CL,[SI]
INC SI
MOV DI,OFFSET FILENAME
A:
MOV AL,[SI]
MOV [DI],AL
INC SI
INC DI
LOOP A
MOV DX,OFFSET FILENAME
;以只读打开文件
MOV AL,00H
MOV AH,3DH
INT 21H
JC ERROR
;将文件内容读入存储区
MOV HANDLE,AX
MOV BX,AX
MOV CX,999
MOV DX,OFFSET ARTICLE
MOV AH,3FH
INT 21H
JC ERROR
MOV ARITCLELEN,AX
JMP INPUTDONE
ERROR:
MOV DX,OFFSET ERRORBUF
MOV AH,09H
INT 21H
INPUTDONE:
POP BX
POP CX
POP AX
POP DX
POP DI
POP SI
RET
INPUT ENDP
转变为大写子程序:
CAPITALOUTPUT PROC
PUSH SI
PUSH DI
PUSH DX
PUSH AX
PUSH CX
PUSH BX
MOV CX,ARITCLELEN
MOV SI,OFFSET ARTICLE
;检查是否是小写字母
B:
MOV AL,[SI]
CMP AL,'a'
JAE CMPZ
INC SI
LOOP B
JMP CAPITALDONE
CMPZ:
CMP AL,'z'
JBE LOWERCASE
INC SI
LOOP B
JMP CAPITALDONE
LOWERCASE:
SUB AL,32
MOV [SI],AL
INC SI
LOOP B
CAPITALDONE:
;输出
MOV DX,OFFSET NEWLINE
MOV AH,09H
INT 21H
MOV DX,OFFSET ARTICLE
MOV AH,09H
INT 21H
POP BX
POP CX
POP AX
POP DX
POP DI
POP SI
RET
CAPITALOUTPUT ENDP
统计词频
CNTOUTPUT PROC
PUSH SI
PUSH DI
PUSH DX
PUSH AX
PUSH CX
PUSH BX
MOV SI,OFFSET ARTICLE
MOV DI,OFFSET CNTBUF
INC DI
MOV CX,ARITCLELEN
MOV BH,00
MOV BL,26
MOV AH,00
MOV DL,00
;双重循环统计词频
C:
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH SI
PUSH DI
D:
MOV AL,[SI]
SUB AL,'A'
CMP AL,AH
JE FOUND
INC SI
JMP NOTFOUND
FOUND:
MOV AL,[DI]
INC AL
DAA
MOV [DI],AL
INC SI
NOTFOUND:
LOOP D
POP DI
POP SI
POP DX
POP CX
POP BX
POP AX
INC AH
ADD DI,03H
DEC BL
JNZ C
;找出key,我想到一个很暴力的算法,用一个数去遍历数组,找比自己大的数统计个数
MOV DI,OFFSET CNTBUF
MOV SI,OFFSET CNTBUF
ADD DI,01H
MOV CH,00H
MOV CL,26
MOV AH,26
;外层循环遍历整个数组
LKEY:
MOV AL,[DI]
MOV BL,[SI]
MOV BH,00H
PUSH BX
PUSH AX
PUSH SI
PUSH DI
;内层循环同样遍历整个数组
MOV DI,OFFSET CNTBUF
INC DI
CMPKEY:
MOV BL,[DI]
CMP AL,BL
JB JUDGE
BREAK:
ADD DI,03H
DEC AH
JNZ CMPKEY
CMP BH,2
JE KEYGET
MOV BH,0
JMP KEYDONE
JUDGE:
INC BH
JMP BREAK
KEYGET:
MOV AL,[SI]
SUB AL,'A'
MOV DI,OFFSET KEY
MOV [DI],AL
KEYDONE:
POP DI
POP SI
POP AX
POP BX
ADD DI,03H
ADD SI,03H
LOOP LKEY
;把统计到的十进制数转换成字符
MOV DI,OFFSET CNTBUF
INC DI
MOV SI,OFFSET CNTBUF
INC SI
MOV BH,00
MOV BL,26
MOV CL,4
E:
MOV AL,[DI]
MOV DL,AL
AND AL,0F0H
ROL AL,CL
ADD AL,'0'
MOV [SI],AL
INC SI
MOV AL,DL
AND AL,0FH
ADD AL,'0'
MOV [SI],AL
ADD SI,02H
ADD DI,03H
DEC BL
JNZ E
;输出
MOV DX,OFFSET NEWLINE
MOV AH,09H
INT 21H
MOV DX,OFFSET NEWLINE
MOV AH,09H
INT 21H
MOV DX,OFFSET CNTBUF
MOV AH,09H
INT 21H
POP BX
POP CX
POP AX
POP DX
POP DI
POP SI
RET
CNTOUTPUT ENDP
加密子程序
ENCRYPTION PROC
PUSH SI
PUSH DI
PUSH DX
PUSH AX
PUSH CX
PUSH BX
MOV SI,OFFSET ARTICLE
MOV CX,ARITCLELEN
MOV DI,OFFSET NUMTABLE
MOV AH,00H
F:
MOV AL,[SI]
;判断是字母还是数字
CMP AL,'0'
JAE CMPNINE
CAPITALJUDGE:
CMP AL,'A'
JAE ENCRYPTIONCMPZ
CONTINUE:
INC SI
LOOP F
JMP ENCRYPTIONDONE
CMPNINE:
CMP AL,'9'
JBE NUMENCRYPTION
JMP CAPITALJUDGE
ENCRYPTIONCMPZ:
CMP AL,'Z'
JBE LETTERENCRYPTION
JMP CONTINUE
;数字加密
NUMENCRYPTION:
PUSH DI
PUSH AX
SUB AL,'0'
ADD DI,AX
MOV AL,[DI]
MOV [SI],AL
POP AX
POP DI
JMP CONTINUE
;字母加密
LETTERENCRYPTION:
PUSH AX
PUSH DI
PUSH BX
SUB AL,'A'
MOV DI,OFFSET KEY
MOV AH,[DI]
ADD AL,AH
MOV AH,00H
MOV BL,26
DIV BL
MOV AL,AH
ADD AL,41H
MOV [SI],AL
POP DI
POP BX
POP AX
JMP CONTINUE
ENCRYPTIONDONE:
MOV DX,OFFSET NEWLINE
MOV AH,09H
INT 21H
MOV DX,OFFSET NEWLINE
MOV AH,09H
INT 21H
MOV DX,OFFSET ARTICLE
MOV AH,09H
INT 21H
POP BX
POP CX
POP AX
POP DX
POP DI
POP SI
RET
ENCRYPTION ENDP
文件输出子程序
SAVE PROC
PUSH SI
PUSH DI
PUSH DX
PUSH AX
PUSH CX
PUSH BX
;创建文件
MOV DX,OFFSET CIPHERFILENAME
MOV CX,00H
MOV AH,3CH
INT 21H
JC OUTPUTERROR
;写入数据
MOV HANDLE,AX
MOV BX,AX
MOV CX,ARITCLELEN
MOV DX,OFFSET ARTICLE
MOV AH,40H
INT 21H
JC OUTPUTERROR
;关闭文件
MOV BX,HANDLE
MOV AH,3EH
INT 21H
JC OUTPUTERROR
JMP OUTPUTDONE
OUTPUTERROR:
MOV AH,09H
MOV DX,OFFSET NEWLINE
INT 21H
MOV AH,09H
MOV DX,OFFSET ERRORBUF
INT 21H
OUTPUTDONE:
POP BX
POP CX
POP AX
POP DX
POP DI
POP SI
RET
SAVE ENDP
运行结果
-
输入文件名,打开文件,将文件中的英文字母变成大写,将新文件内容显示
输入文件名为1.txt
-
统计字母出现频率,输出结果
A53表示共有53个A,后续同理
-
根据规则进行加密
加密结果打印在屏幕上
-
最终输出文件
NYRKARG VF N PBAIBYHGVBANY ARHENY ARGJBEX GUNG VF GENVARQ BA ZBER GUNA N ZVYYVBA VZNTRF SEBZ GUR VZNTRARG QNGNONFR [13684]. GUR ARGJBEX VF 2 YNLREF QRRC NAQ PNA PYNFFVSL VZNTRF VAGB 5777 BOWRPG PNGRTBEVRF, FHPU NF XRLOBNEQ, ZBHFR, CRAPVY, NAQ ZNAL NAVZNYF. NF N ERFHYG, GUR ARGJBEX UNF YRNEARQ EVPU SRNGHER ERCERFRAGNGVBAF SBE N JVQR ENATR BS VZNTRF. GUR ARGJBEX UNF NA VZNTR VACHG FVMR BS 990-OL-990. SBE ZBER CERGENVARQ ARGJBEXF VA ZNGYNO, FRR CERGENVARQ PBAIBYHGVBANY ARHENY ARGJBEXF.
LBH PNA HFR PYNFFVSL GB PYNFFVSL ARJ VZNTRF HFVAT GUR NYRKARG ARGJBEX. SBYYBJ GUR FGRCF BS PYNFFVSL VZNTR HFVAT TBBTYRARG NAQ ERCYNPR TBBTYRARG JVGU NYRKARG.