⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 edit.asm

📁 汇编语言课程设计 包含源码 和 详细的 文档报告
💻 ASM
字号:
DATAS SEGMENT
    ;此处输入数据段代码 
    mode DB 03,80,25			;显示方式以及显示大小
    color DB 1FH			;窗口的背景色和前景色
    cursor	DB 0,0			;光标的位置(行和列)
    position	DB 0,0,0,0	;光标的当前位置(行和列)(在显示范围内)
    						;以及左上角字符所在的行和列,为ReDisplay传递参数
    place	DB 0,0			;屏幕第一行显示的是第多少行
    insert	DB 1			;标示事Insert还是Override
    ctrlKey DB 0			;ctrl是否按下,1表示按下
    
    fileName DB 30,0,30 DUP (?),0   ;文件的路径及文件名
    fileName1 DB 'E:\program\data.txt',0
    handle	 DW ?				;文件句柄
    mesg1	 DB 'Please input file name:','$'
    mesg2	 DB 'Failed to open file!!','$'
    mesg3	 DB 'Failed to read file!!','$'
    
         
DATAS ENDS

EDATAS	SEGMENT
	;附加数据段,定义缓冲区
	;buf的第一个字节为已经输入的行数(总行数为200)
	;后面的为一个二维数组,每一行记录一行字符,每一行的
	;第一字符为该行输入的字符数
	buf	 DB 1,200 DUP (0,200 DUP (' '))
	bufsize DB 200,200			;能输入的最大行数和列数
	ctrlInfile DB 0DH,0AH,0
	
EDATAS	ENDS

STACKS SEGMENT
    ;此处输入堆栈段代码
    stack	DW 300 DUP (?)
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
;----------------------------------------------
;接收键盘的输入(调用BIOS)
;----------------------------------------------
INPUT	MACRO
	;取键盘的状态字
	MOV AH, 02H
	INT 16H
	TEST AL, 04H		;测试Ctrl键
	JZ getChar
	MOV ctrlKey, 1
 getChar:	
	MOV AH,0
	INT 16H
	
	ENDM
;----------------------------------------------
;读取光标的当前位置
;----------------------------------------------
READCURSOR	MACRO
	MOV BH, 0
	MOV AH, 3H
	INT 10H
	MOV position, DH
	MOV position[1], DL
	ENDM
;----------------------------------------------

    MOV AX,DATAS
    MOV DS,AX
    MOV AX, EDATAS
    MOV ES, AX
    MOV AX, STACKS
    MOV SS, AX
    ;此处输入代码段代码
    
	;初始化窗口
    CALL InitWindow
    
    MOV AH,0CH		;清空键盘的缓冲区
    MOV AL,00H
    INT 21H 
    
    ;接收输入并显示
 inputAndDisplay:   
    INPUT
    CMP AH, 01H			;按下Esc键
    JZ exit
    CMP ctrlKey, 1		;判断是否按下crtl
    JZ others 
    CMP	AL, 0
    JZ contrl
    CMP AL, 0DH
    JZ contrl
    CMP AH, 0EH
    JZ contrl
    CALL SaveAndDisplay			;保存并显示输入
    JMP inputAndDisplay
    
 contrl:
 	CMP AL, 0DH
 	JNZ n1
 	CALL crlf			;回车换行
 	JMP inputAndDisplay		
 n1:
 	CMP AH, 48H
 	JNZ n2
 	CALL up				;↑,光标向上移动一行
 	JMP inputAndDisplay		
 n2:
 	CMP AH, 4BH
 	JNZ n3
 	CALL left			;←,光标向左移动一列
 	JMP inputAndDisplay		
 n3:
 	CMP AH, 4DH
 	JNZ n4
 	CALL right			;→,光标向右移动一列
 	JMP inputAndDisplay	
 n4:
 	CMP AH, 50H
 	JNZ n5
 	CALL down			;↓,光标向下移动一行
 	JMP inputAndDisplay	
 n5:
 	CMP AH, 53H			;Delete键
 	JNZ n6
 	CALL Delete
 	JMP inputAndDisplay	
 n6:
 	CMP AH, 0EH			;Backspace键
 	JNZ n7
 	CALL Backspace
 	JMP inputAndDisplay	
 n7:
 	CMP AH, 3BH			;F1打开文件
 	JNZ n8
 	CALL openFile
 	JMP inputAndDisplay	
 n8:
 	CMP AH, 3CH			;F2保存文件
 	JNZ  inputAndDisplay	
 	CALL saveFile
 	JMP inputAndDisplay	
 	
 others:
 	CMP AL, 's'
 	JNZ inputAndDisplay
 	CALL saveFile
 	JMP inputAndDisplay	  
 	  
 Exit:       		;推出
    MOV AH,4CH
    INT 21H
;----------------------------------------------
;初始化窗口
;----------------------------------------------
InitWindow		PROC NEAR
	PUSH AX
	PUSH BX
	PUSH CX
	PUSH DX

    MOV	AL, mode	;设置显示方式
	MOV AH, 0
	INT 10H
	
	MOV AH, 06H		;设置背景色
	MOV AL, 0
	MOV BH, color
	MOV CH, 0
	MOV CL, 0
	MOV DH, 24
	MOV DL, 79
	INT 10H
	
	POP DX
	POP CX
	POP BX
	POP AX
	RET
InitWindow		ENDP
;---------------------------------------------- 
;保存输入并显示
;----------------------------------------------
SaveAndDisplay		PROC NEAR
	PUSH	BX
	PUSH	CX
	PUSH	DX
	PUSH	AX
	;读取光标的当前位置
	READCURSOR
	;获得该行已经输入的字符数[cursor]*(ES:[bufsize+1]+1)
	MOV AL, cursor
	MOV BL, ES:bufsize[1]
	INC BL
	MUL	BL
	MOV DI, AX
	INC DI 
	MOV BL, ES:buf[DI]
	CMP BL, ES:bufsize[1]
	JZ	over			;该行已经不能再输入的字符
	
	MOV BH, cursor[1]	;获得光标的位置(列数)
	INC BH
	CMP BH, BL			;比较[cursor+1]和已经输入的字符数
	JBE moveChar1
	MOV CL, cursor[1]
	MOV ES:buf[DI], CL
	JMP saveChar
 moveChar1:	
	CALL MoveChar		;移动字符
 saveChar:				;保存输入的字符
 	INC cursor[1]		;重新设置cursor
 	INC ES:buf[DI]	;重设已经输入的字符数
 	MOV CL, ES:buf[DI]
 	MOV CH, 0
 	MOV SI, CX			;保存输入的字符数
 	INC BL
 	MOV CL, BH
 	MOV CH, 0
 	ADD DI, CX
 	POP AX
 	MOV ES:buf[DI], AL 	
 	
 	;对光标的位置进行判断
 	MOV AL, position[1]
 	INC AL
 	CMP AL, mode[1]		
 	JNZ display
 	;重新显示每一行
 	MOV AL, cursor			;设置参数
 	SUB AL, position
 	MOV position[2], AL
 	MOV AL, cursor[1]
 	SUB AL, position[1]
 	MOV position[3], AL
 	CALL ReDisplay			;光标在最右边
 	JMP over	
 display:	
 	;显示
 	;MOV CL, BL
	;SUB CL, BH
	;MOV CH, 0
	;INC CX
	;MOV CX, 1
	MOV CX, SI
	SUB CL, cursor[1]
	INC CX
	CMP CX, 80
	JB d1
	MOV CX, 80
	SUB CL, position[1]
	;MOV CL, mode[1]
	;SUB CL, position[1]
	;MOV CH, 0
	;DEC CX
 d1:	
 	LEA BP, ES:buf[DI]
 	MOV AL, 1
 	MOV BL, 1FH
 	MOV BH, 0
 	MOV AH, 13H	
 	INT 10H	
 	
 	;重置光标
 	MOV BH, 0
 	MOV DH, position
 	MOV DL, position[1]
 	INC DL
 	MOV AH, 02H
 	INT 10H


	
 over:
 	POP DX
 	POP CX
 	POP BX
	RET
SaveAndDisplay		ENDP
;----------------------------------------------
;将缓冲区的字符顺次向后移一个(光标后的字符)
;----------------------------------------------
MoveChar	PROC NEAR
	PUSH CX            
	PUSH DI
	;计算该行最后一个字符的偏移地址
	MOV CL, BL
	MOV CH, 0	;DX中是该行的字符数
	ADD DI, CX	
	
	MOV CL, BL
	SUB CL, BH
	INC CL
 n:		
	MOV CH, ES:buf[DI]
	MOV ES:buf[DI+1], CH
	DEC DI
	DEC CL
	JNZ n
	
	POP DI
	POP CX
	RET
MoveChar	ENDP
;----------------------------------------------
;显示[cursor+1]-79到[cursor+1]之间的字符(所有的行)
;调用之前要设置position的值
;----------------------------------------------
ReDisplay	PROC NEAR
	PUSH CX
	PUSH AX
	PUSH BX
	PUSH DX
	PUSH DI
	PUSH SI
	
	MOV BL, ES:bufsize[1]
	INC BL
	MOV BH, 0
	MOV DI, BX			;设置增量
	
	;计算左上角字符的地址
	MOV AL, position[2]
	MUL	BL				;*增量
	MOV BL, position[3]
	MOV BH, 0
	ADD AX, BX
	INC AX
	INC AX
	MOV BP, AX
	
	MOV AL, ES:buf		;读取已经输入的行数
	SUB AL, position[2]
	MOV AH, 0
	MOV SI, AX
	;INC SI
	;MOV DL, ES:bufsize[1]
	;MOV DH, 0
	MOV DH, 0 
 	;MOV DL, 0
nextLine:
	MOV DL, 0	
	MOV CX, 80
	MOV AL, 1
 	MOV BL, 1FH
 	MOV BH, 0 
 	 
 	MOV AH, 13H	
 	INT 10H
 	
 	ADD BP, DI
 	INC DH	
 	DEC SI
  	JNZ nextLine
	
	;置光标的位置
	MOV BH, 0
	MOV DH, position
	MOV DL, position[1]
	MOV AH, 02H
	INT 10H
	
	
	POP SI
	POP DI
	POP DX
	POP BX
	POP AX
	POP CX
	RET
ReDisplay	ENDP
;----------------------------------------------
;----------------------------------------------
crlf	PROC NEAR
	PUSH DX
	PUSH AX
	;读取光标的当前位置

	
	INC cursor		;设置行号
	MOV cursor[1], 0
	INC ES:buf
				
	MOV BH, 0		;读取光标的位置
	MOV AH, 03H
	INT 10H
	MOV DL, 0H
	INC DH
	MOV AH, 02H
	INT 10H
 	READCURSOR
 	MOV AL, cursor			;设置参数
 	SUB AL, position
 	MOV position[2], AL
 	MOV position[3], 0
	CALL ReDisplay

	
	POP AX
	POP DX
	RET
crlf	ENDP
;----------------------------------------------
;光标向上移动
;----------------------------------------------
up		PROC NEAR
	PUSH AX
	
	MOV AL, cursor
	CMP AL, 0
	JZ up2			;如果光标在第一行则不能移动
	
	
	MOV BH, 0		;读取光标的位置
	MOV AH, 03H
	INT 10H
	CMP DH, 0		;光标在屏幕的最上方
	JNZ up1
	DEC cursor			;设置参数
	INC DH
	MOV position, DH
	MOV position[1], DL
	MOV AH, cursor
	SUB AH, DH
	MOV position[2], AH
	MOV AH, cursor[1]
	SUB AH, DL
	MOV position[3], AH
	CALL ReDisplay		;重新显示每一行
	JMP up2
 up1:
 	DEC cursor
	DEC DH			;重置光标的位置
	MOV AH, 02H
	INT 10H
	
 up2:
	POP AX
	RET
up		ENDP
;----------------------------------------------
;光标向左移动
;----------------------------------------------
left	PROC NEAR
	MOV BH, 0		;读取光标的位置
	MOV AH, 03H
	INT 10H
	CMP DL, 0
	JNZ left1
	CMP cursor[1], 0
	JZ left2
	DEC cursor[1]			;设置参数
	;DEC DL
	MOV position, DH
	MOV position[1], DL
	MOV AH, cursor
	SUB AH, DH
	MOV position[2], AH
	MOV AH, cursor[1]
	SUB AH, DL
	MOV position[3], AH
	CALL ReDisplay		;重新显示每一行
	JMP left2
 left1:
 	DEC cursor[1]
 	DEC DL
 	MOV AH, 02H
 	INT 10H	
 left2:	
	RET
left 	ENDP
;----------------------------------------------
;光标向右移动
;----------------------------------------------
right	PROC NEAR
	MOV BH, 0		;读取光标的位置
	MOV AH, 03H
	INT 10H
	CMP DL, 79
	JNZ right1
	CMP cursor[1], 199
	JZ right2
	INC cursor[1]			;设置参数
	;DEC DL
	MOV position, DH
	MOV position[1], DL
	MOV AH, cursor
	SUB AH, DH
	MOV position[2], AH
	MOV AH, cursor[1]
	SUB AH, DL
	MOV position[3], AH
	CALL ReDisplay		;重新显示每一行
	JMP right2
 right1:
 	INC cursor[1]
 	INC DL
 	MOV AH, 02H
 	INT 10H
 right2:	
	RET
right	ENDP
;----------------------------------------------
;光标向下移动
;----------------------------------------------
down 	PROC NEAR

	MOV BH, 0		;读取光标的位置
	MOV AH, 03H
	INT 10H
	MOV AH, mode[2]
	DEC AH
	CMP DH, AH		;判断光标是否在屏幕的最下方
	JNZ down1
	INC cursor			;设置参数
	DEC DH
	MOV position, DH
	MOV position[1], DL
	MOV AH, cursor
	SUB AH, DH
	MOV position[2], AH
	MOV AH, cursor[1]
	SUB AH, DL
	MOV position[3], AH
	CALL ReDisplay		;重新显示每一行
 down1:	
 	INC cursor
	INC DH			;重置光标的位置
	MOV AH, 02H
	INT 10H
 down2:	
	RET
down 	ENDP
;----------------------------------------------
;删除光标处的字符
;----------------------------------------------
Delete		PROC NEAR
	;计算该行字符数的地址
	MOV AL, cursor
	MOV BL, ES:bufsize[1]
	INC BL
	MUL BL
	INC AX
	MOV DI, AX
	;判断需不需要删除
	MOV CL, ES:buf[DI]
	
	;DEC CL
	SUB CL, cursor[1]
	JBE	delete2
	;计算光标处对应的缓冲区地址
	DEC ES:buf[DI]		;字符数减一个
	MOV AL, cursor[1]
	MOV AH, 0
	ADD DI, AX
	INC DI
	MOV BX, DI
		
	;移动缓冲区的内容
	MOV CH, 0		;CX保存移动字符数
	MOV SI, CX
 delete1:	
	MOV AL, ES:buf[DI+1]
	MOV ES:buf[DI], AL
	
	INC DI
	DEC CX
	JNZ delete1
	
	MOV ES:buf[DI], ' '
	
	;重新显示光标后的字符
	READCURSOR
	MOV CX, SI
	LEA BP, ES:buf[BX]
	MOV AL, 1
	MOV BH, 0
	MOV BL, 1FH 
	MOV AH, 13H
	INT 10H	
	
	 ;重置光标
 	MOV BH, 0
 	MOV DH, position
 	MOV DL, position[1]
 	MOV AH, 02H
 	INT 10H
	
 delete2:	
	RET
Delete		ENDP
;----------------------------------------------
;用Backspace删除光标前一个的字符
;----------------------------------------------
Backspace		PROC NEAR
	;计算该行字符数的地址
	MOV AL, cursor
	MOV BL, ES:bufsize[1]
	INC BL
	MUL BL
	INC AX
	MOV DI, AX
	;判断需不需要删除
	MOV CL, ES:buf[DI]
	;DEC CL
	SUB CL, cursor[1]
	JB	delete2
	;计算光标处对应的缓冲区地址
	DEC ES:buf[DI]		;字符数减一个
	MOV AL, cursor[1]
	MOV AH, 0
	ADD DI, AX
	;INC DI
	MOV BX, DI
		
	;移动缓冲区的内容
	INC CL
	MOV CH, 0		;CX保存移动字符数
	MOV SI, CX
 backspace1:	
	MOV AL, ES:buf[DI+1]
	MOV ES:buf[DI], AL
	
	INC DI
	DEC CX
	JNZ backspace1
	
	MOV ES:buf[DI], ' '
	
	;重新显示光标后的字符
	READCURSOR
	DEC DL
	MOV CX, SI
	LEA BP, ES:buf[BX]
	MOV AL, 1
	MOV BH, 0 
	MOV BL, 1FH 
	MOV AH, 13H
	INT 10H	
	
	 ;重置光标
	DEC cursor[1]
 	MOV BH, 0
 	MOV DH, position
 	MOV DL, position[1]
 	DEC DL
 	MOV AH, 02H
 	INT 10H
	
 backspace2:	
	RET
Backspace		ENDP
;---------------------------------------------
;打开一个文件
;---------------------------------------------
openFile		PROC NEAR
	;清空窗口
	MOV AH, 06H		
	MOV AL, 0
	MOV BH, 04H
	MOV CH, 0
	MOV CL, 0
	MOV DH, 24
	MOV DL, 79
	INT 10H
	
	;输出提示信息
	MOV BH, 0			;置光标
	MOV DX, 0
	MOV AH, 02H
	INT 10H
	
	MOV AH, 09H
	MOV DX, OFFSET mesg1
	INT 21H
	
	;输入文件名
	MOV AH, 0AH
	MOV DX, OFFSET fileName
	INT 21H
	MOV BL, fileName[1]
	ADD BL, 2
	MOV BH, 0
	MOV fileName[BX], 0
	
	;打开文件
    MOV AH, 3DH
    MOV AL, 2			;设置访问模式
    LEA DX, fileName[2]
    INT 21H
    
    JNC	read	
    MOV DL, 0AH
    MOV AH, 02H
    INT 21H
    MOV DL, 0DH
    MOV AH, 02H
    INT 21H
    LEA DX, mesg2		;打开文件失败
 	MOV AH, 09H
 	INT 21H
 	JMP EXIT
 read:
 	MOV handle, AX		;保存文件句柄
 	PUSH DS
 	PUSH ES
 	MOV BX, ES			;交换DS和ES
 	MOV AX, DS
 	MOV DS, BX
 	MOV ES, AX
 	MOV SI, 1
 	
 next1:	
 	INC DI
 	MOV AH, 3FH		;读入文件内容
 	MOV BX, ES:handle
 	;MOV CL, DS:bufsize[1]
 	;MOV CH, 0
 	MOV CX, 1
 	LEA DX, DS:buf[DI]
 	INT 21H
  	
 	JNC	next2	
    MOV DL, 0AH
    MOV AH, 02H
    INT 21H
    MOV DL, 0DH
    MOV AH, 02H
    INT 21H
    LEA DX, ES:mesg3		;读入文件失败
 	MOV AH, 09H
 	INT 21H
 	JMP EXIT 
 next2: 
 	CMP	AX, 0	
 	JZ next4	
 	CMP DS:buf[DI], 0AH
 	JZ next3
 	CMP DS:buf[DI], 0DH
 	JZ next3
	
 	INC DS:buf[SI]
 	JMP next1
 next3:	
 	MOV DS:buf[DI], ' '
	MOV AH, 3FH
	MOV CX, 1
	LEA DX, DS:ctrlInfile[2]
	INT 21H
	
 	INC DS:buf
 	ADD SI, 201
 	;ADD DI, 201
 	MOV DI, SI
 	JMP next1
 	
 	JNZ next1
 next4:	
 	POP ES
 	POP DS
 	
 	;关闭文件
 	MOV AH, 3EH
 	INT 21H 
 	
 	DEC ES:buf
 	CALL InitWindow
 	CALL ReDisplay 
	RET
openFile		ENDP
;----------------------------------------------
;保存文件
;----------------------------------------------
saveFile	PROC NEAR
	PUSH DS
	;打开文件
	MOV AH, 3DH
	MOV AL, 2
	LEA DX, fileName1
	INT 21H
	MOV BX, AX
	
	MOV AL, ES:buf 		;循环次数
	MOV AH, 0
	MOV SI, AX
	MOV DI, 1
	MOV AX, ES
	MOV DS, AX
 L1:		
	MOV CL, ES:buf[DI]
	MOV CH, 0
	LEA DX, ES:buf[DI+1]
	;LEA DX, ES:buf[DI]
	MOV AH, 40H
	INT 21H
	
	LEA DX, ES:ctrlInfile
	MOV AH, 40H
	MOV CX, 2
	INT 21H
	
	ADD DI,201
	DEC SI
	JNZ L1
	
	;关闭文件
 	MOV AH, 3EH
 	INT 21H 
 	
 	POP DS
	RET
saveFile	ENDP
;----------------------------------------------
CODES ENDS
    END START

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -