DOS_8086_汇编写一个带窗口的文本输入程序

 

汇编程序:

;***************************************************************************************
;  功能:开个窗口,做个窗框,把光标定位在窗口内,显示信息,简单的上卷下卷,末行控制,回车处理
;***************************************************************************************

CODES SEGMENT
    ASSUME CS:CODES
    
;----------------------------------------------------------------------------------
;主程序
TextWindow  proc   			far
	
	call  Initializing
	call  get_char
	ret
TextWindow				endp

;----------------------------------------------------------------------------------
;屏幕初始化
Initializing	proc		        near
	push  ax
	push  bx
	push  cx
	push  dx
    ;设置外窗口属性
    MOV   AH,7				;功能:屏幕初始化
    MOV   AL,0				;page
    MOV   BH,70H			;白底黑字
    MOV   CH,1				;row左上
    MOV   CL,2				;column左上
    MOV   DH,23				;row右下
    MOV   DL,77				;column右下
    INT   10H				;BIOS显示操作中断
    
    ;设置内窗口属性
    MOV   AH,7				;功能:屏幕初始化
    MOV   AL,0				;page
    MOV   BH,3FH			;浅青色底白字
    MOV   CH,2				;row左上
    MOV   CL,4				;column左上
    MOV   DH,22				;row右下
    MOV   DL,75				;column右下
    INT   10H				;BIOS显示操作中断
    
    ;设置光标类型(大小)
    MOV   CH,12				;光标起始行
    MOV   CL,13				;光标结束行
    MOV   AH,1				;设置光标类型
    INT   10H				;DOS中断:显示操作
    ;初始化光标位置
    MOV   DH,2				;屏幕显示行
    MOV   DL,4				;屏幕显示列
    MOV   BH,0				;显示页号
    MOV   AH,2				;置光标位置
    INT   10H				;BIOS显示操作中断
    
    pop   dx
    pop   cx
    pop   bx
    pop   ax
    ret
Initializing                endp

;----------------------------------------------------------------------------------
;键盘输入,直到Esc退出
get_char  proc				near
	push  ax
	push  dx
	
	mov   ah,1			; 功能:从键盘输入一个字符并回显
	int   21h
	
	cmp   al,1bh			; 判断按键是否ESC√
	jz    exit
	
	cmp   al,0DH			; 判断是否为回车键(要注意回车后不返回,而是等待继续输入)
	jz    EnterDeal			; 调转 回车键处理
	
	mov   ah,3			; 读取当前光标位置
	;mov  bh,0			; 页号
	int   10h			; BIOS显示操作中断
	
	cmp   dl,76			; 判断是否最后一列(75+1)√(可用于设置字符显示宽度)
	jz    LastColumn		; 跳转 末列处理
	
	loop  get_char			; 继续输入
	
	pop   dx
	pop   ax
	
;退出程序
exit:
	mov   ah,4ch
	int   21h			;DOS中断
get_char				endp
	
;----------------------------------------------------------------------------------
;回车键处理-----------------;(把回车控制到内窗口-不处理会跳到屏幕左边界)
EnterDeal proc				near
	push  ax
	push  dx

	mov   ah,3			; 读取 当前光标位置
	;mov  bh,0			; 页号
	int   10h			; BIOS显示操作中断
	
	mov   ah,2			; 功能:置光标位置
	;mov  dh,?			; 保持当前行
	mov   dl,4			; 光标置内窗口左边界
	;mov  bh,0			; 页号--------------测试省略:可省略√
	int   10h			; BIOS显示操作中断
	
	jmp   LastLine			; 继续 末行判断
	
	pop   dx
	pop   ax
	ret				; 返回主程序
EnterDeal				endp

;----------------------------------------------------------------------------------
;末列处理
LastColumn     proc			near
	push  ax
	push  dx

	mov   ah,3			; 读取当前光标位置
	;mov  bh,0			; 页号
	int   10h			; BIOS显示操作中断
	
	mov   ah,2			; 功能:置光标位置
	add   dh,1			; 光标置下一行
	mov   dl,4			; 光标置内窗口左边界
	;mov  bh,0			; 页号
	int   10h			; BIOS显示操作中断
	
	jmp   LastLine			; 继续 末行判断
	
	pop   dx
	pop   ax
	ret				; 返回主程序
LastColumn				endp

;----------------------------------------------------------------------------------
;末行判断-------------------; 末行(22+1)需要卷屏并上移光标
LastLine  proc				near
	push  ax
	push  dx

	mov   ah,3			; 读取当前光标位置
	;mov  bh,0			; 页号
	int   10h			; BIOS显示操作中断
	
	cmp   dh,23			; 判断是否最后一行(22+1)
	jne   get_char		        ; 否:继续输入
	
	;-----------------------        ; 是:卷屏1行并上移光标
	call  scroll_screen 	        ; 调用 屏幕滚动
	
	mov   ah,3			; 读取当前光标位置
	;mov  bh,0			; 页号
	int   10h			; BIOS显示操作中断
	
	mov   ah,2			; 功能:置光标位置
	mov   dh,22			; 光标置内窗口左边界
	mov   dl,4			; 光标置内窗口左边界
	int   10h			; BIOS显示操作中断
	
	pop   dx
	pop   ax
	jmp   get_char		        ; 继续输入
Lastline			        endp
	
;----------------------------------------------------------------------------------
;屏幕每次上卷1行----------------          ; 屏幕滚动必须要设置窗口滚动的范围,即cx,dx
scroll_screen	proc		near
	push  ax
	push  bx
	push  cx
	push  dx

	mov	  al,1			; 上卷的行数
	mov	  bh,2FH		; 
	mov   ch,2
	mov   cl,4
	mov   dh,22			; 整屏滚动
	mov   dl,75
	mov	  ah,6			; 功能:屏幕上卷
	int   10h			; BIOS显示操作中断
	
	pop   dx
	pop   cx
	pop   bx
	pop   ax
	ret				; 返回调用程序
scroll_screen			        endp

;----------------------------------------------------------------------------------
CODES ENDS
;**********************************************************************************
    END   TextWindow
    

运行情况:

图[1]  运行情况

功能描述:

  1. 连续输入字符串,到内窗口边界后跳到下一行;
  2. 任意位置按Enter键跳到下一行;
  3. 任意位置按ESC键就退出程序;
  4. 当输入到最后一行后,按Enter键和输入字符超过内窗口都会触发屏幕上卷,并跳到下一行;
  5. 屏幕上卷用了不同的底色,为了便于观察卷屏效果;
  6. 按退格键Backspace可以将光标往前移,这时候键入字符就会重写,可用于字符修正;
  7. 方向键、翻页键等其他按键都没有做功能,按下这些键只会显示按键的标志码;
  8. 一直按退格键会将光标移出内窗口,这个问题没有处理;
  9. 程序只是演示窗口输入和光标、内容控制,不保存字符串,只是写显存而已。
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个汇编语言程序,可以在DOSBox中运行,并且实现了一个计时器,每秒钟会自动加一,并在DOSBox窗口中心处显示时间。同时,程序还能够响应键盘输入,按下ESC键时程序会退出。 ``` .model small .stack 100h .data msg db '00:00:00$' xpos dw ? ypos dw ? width dw ? height dw ? .code main proc mov ax, @data mov ds, ax mov byte ptr msg+7, '0' ; 初始秒数 mov byte ptr msg+4, '0' ; 初始分钟数 mov byte ptr msg+1, '0' ; 初始小时数 mov ah, 0Fh ; 获取文本模式光标位置和大小 int 10h mov width, cx mov height, dx mov xpos, width/2-4 ; 字符串长度为8,所以要减4 mov ypos, height/2 mov ah, 2 ; 显示字符串 mov dx, offset msg mov bh, 0 ; 页面号 mov cx, xpos ; 列 mov dl, ypos ; 行 int 10h mov ah, 0 int 16h ; 等待键盘输入 mov ah, 0 int 1ah ; 获取系统时间 mov al, dh ; 秒数 sub al, '0' mov byte ptr msg+7, al mov al, dl ; 分钟数 sub al, '0' mov byte ptr msg+4, al mov al, cl ; 小时数 sub al, '0' mov byte ptr msg+1, al mov ah, 2 ; 显示字符串 mov dx, offset msg mov bh, 0 ; 页面号 mov cx, xpos ; 列 mov dl, ypos ; 行 int 10h cmp ah, 1Ch ; ESC键的扫描码是1Ch jne main mov ah, 4ch int 21h main endp end main ``` 在这个程序中,我们首先使用BIOS中断0Fh获取文本模式光标位置和大小,然后计算出字符串的初始位置。接着,在更新时间时,我们使用BIOS中断10h来将字符串显示在屏幕中心。这样可以让程序界面更加美观。 该程序的编译和运行方式可以参考以下步骤: 1. 将上述代码保存到一个文件中,例如timer.asm。 2. 打开DOSBox,进入程序所在的目录。 3. 输入以下命令编译程序: ``` tasm timer.asm tlink timer.obj ``` 4. 输入以下命令运行程序: ``` timer.exe ``` 5. 程序开始运行,可以按下ESC键退出。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值