首页 > 编程语言 >汇编实验:基于BIOS调用(10H)的多窗口输出程序

汇编实验:基于BIOS调用(10H)的多窗口输出程序

时间:2022-11-29 15:24:31浏览次数:51  
标签:10H 上卷 窗口 函数 箭头 多窗口 mov BIOS 光标

汇编实验报告-屏幕窗口程序实验

1. 题目要求:自行编写一个键盘输入并且在屏幕输出的程序,它可以完成键盘读入并且在屏幕显示出来。具体要求:

image-20221109144849693 image-20221109144902289

2. 运行环境:Windows11+MASM

3. 题目分析:

题目要求建立三个窗口用于回显,利用BIOS调用的10H中的6号命令可以完成将屏幕中给定范围的矩形区域上卷n行,因此我们可以使用该命令划分出三个窗口的形状。

此外,题目要求我们的所有输入都要在最下方窗口显示,默认也会在右窗口显示,但是使用左右箭头可以切换显示屏幕。因此我们需要动态的置光标于指定位置,这个可以使用类型10H的0A号命令完成,只要给定光标所在的行列坐标即可。

最后考虑左右箭头切换屏幕的问题。由于左右箭头不是可显示字符,没有ASCII码,因此我们要利用键盘中断获取的扫描码进行判断。搜索可知左右箭头的扫描码分别为4BH、4DH.取扫描码可以使用BIOS调用的16H类型的0号命令,AH中即为扫描码,AL中为ASCII码(如果有)。并且判断完之后,还可以直接利用AL存储ASCII这一点进行显示输出。

4. 流程图绘制:根据分析和题目要求绘制主函数的流程图:

image-20221109150326752

根据主函数流程图,可以编写主函数程序如下:

main proc 
    push ds
    mov ax,data
    mov ds,ax
    call clear
    scroll 11,win1_ulc,win1_ulr,win1_lrc,win1_lrr
    scroll 11,win2_ulc,win2_ulr,win2_lrc,win2_lrr
    scroll  1,win3_ulc,win3_ulr,win3_lrc,win3_lrr
myloop:
    call get_char
    call display
    jmp myloop
main endp

5. 各部分与功能的流程图/程序:

  1. 数据段定义:当我们定义数据段时,我们要考虑的有以下几方面因素:
  • 三个窗口的光标起始位置:因为回显时使用的BIOS调用需要光标的x,y坐标,而光标定位到三个窗口的左下角,因此我们需要分别设置三个窗口左下角的行列号。

  • 三个屏幕的位置坐标:我们使用上卷的方式显示三个窗口,而10h类型的6号命令需要提供窗口的左上角坐标和右下角坐标,因此我们需要分别定义win1\win2\win3的左上角、右下角的行号和列号。

  • 判断光标在左还是右的flag:因为题目要求按下左右箭头实现屏幕显示的切换,因此我们的get_char函数中需要对左右窗口进行设置,而display函数则需要知道在左还是右窗口进行显示。要实现这个功能,可以引入一个flag,为1则表示在右窗口,反之在左。

    数据段定义(较长,同类型的以...省略):

data segment
win1x db 15;左窗口光标
...
win3y db 15
win1_ulc db 10;win1左上列
...
win3_lrr db 22
isright db 1;flag,判断是否在右窗口
data ends
  1. 置光标位置函数curse:
    这两个函数主要执行的功能是根据给定的坐标把光标置于该位置,使用10H中断即可,实现比较简单。不过由于该函数被diplay调用,此时AL中可能存储着要输出字符的ASCII,因此要保护一下。

    但由于本实验多次反复使用该函数,该函数需要光标位置的行、列号,但我们将行列号存储在内存单元中(win1x,win1y,win2x......),则在每次调用子函数之前,都需要通过寄存器设置这两个存储,在curse中再使用寄存器读取,比较麻烦。若使用宏编程方式,可以直接使用形式参数接收主函数提供的实参,因此在调用时实参可以直接写内存单元名win1x,win1y等等,更加方便。

  • 流程图
    image-20221109154013291
  • 程序段代码如下:
curse  MACRO x,y ;置光标位置
  push ax
  mov dh,x
  mov dl,y
  mov bh,0
  mov ah,2
  int 10h
  pop ax
ENDM
  1. 屏幕上卷函数scroll

    该函数功能为将给定屏幕上卷指定行数,使用10H中断的6号命令即可。与curse函数类似,由于本函数一共需要5个参数,如果编写子程序需要用寄存器对这些地址单元依次存取,比较麻烦,因此也采用宏的方式编写,使用形式参数接收实参即可。同理,也要考虑保护AX寄存器。

  • 流程图

    image-20221109154832224
  • 程序段代码如下:

scroll MACRO cnt,ulc,ulr,lrc,lrr  ;窗口上卷cnt行
    push ax;AX里可能有字符
    mov al,cnt;卷cnt行
    mov ch,ulr
    mov cl,ulc
    mov dh,lrr
    mov dl,lrc
    mov ah,6
    mov bh,24h
    int 10h
    pop ax
ENDM
  1. 键盘输入与控制字符判断函数get_char

    该函数功能是利用键盘中断获取字符的扫描码和ASCII码,用扫描码判断是否为左右箭头或ESC,若是则执行对应控制命令;将非控制字符的ASCII码存在AL寄存器,留待display展示。

    • 流程图

      image-20221109160309724
    • 代码段如下:

get_char proc near;获取字符,判断是否是左右箭头和esc。注意我们这里不在意现在光标在win1/win2
input:
    mov ah,0
    int 16h;BIOS,ah存扫描码,al存ASCII码
    cmp ah,4bh;左箭头
    jnz no_left;若不是,继续判断
    mov isright,0;是,切换光标
    jmp input;不可输出箭头,需要再接收
no_left:
    cmp ah,4dh;右箭头
    jnz no_right;也不是右箭头
    mov isright,1
    jmp input;不可输出箭头,需要再接收
no_right:
    cmp ah,01;ESC
    jnz get_complete;说明不是控制字符,回主函数准备输出
    mov ah,4ch
    int 21h;ESC,结束整个程序
get_complete:
    ret;回主函数,此时al保存着字符
get_char endp
  1. 输出与上卷判断函数display

    该函数功能是将AL中字符输出到下方窗口,以及左右窗口的其中一个,并在输出完成后判断是否应该上卷。(本函数调用的output1只是对BIOS调用10H的封装,不再赘述)

    • 流程图

      image-20221109161615023
    • 代码段较长,这里不再附上,可参看附件中的源程序。

6.运行结果

  1. 输入,默认在下窗口、右窗口显示。可以看到当右侧窗口光标进行到行末后,右侧屏幕会上卷一行。

    image-20221109161819948
  2. 按下左箭头,继续输入,可以看到左窗口和下窗口开始显示内容。可以看到左、下窗口的上卷也成功实现。由于下窗口只有一行,所以上卷后只留下新一行的信息。

    image-20221109161957796
  3. 当左/右窗口输满时,最上一行会上卷消失:

    image-20221109162206673

    可见功能均正常实现。

标签:10H,上卷,窗口,函数,箭头,多窗口,mov,BIOS,光标
From: https://www.cnblogs.com/czy-blogs/p/16935460.html

相关文章

  • BIOS设置 翻译中文图文教程(一)
    BIOS设置图解教程­BIOS(基本输入/输出系统)是被固化在计算机CMOSRAM芯片中的一组程序,为计算机提供最初的、最直接的硬件控制。BIOS主要有两类∶AWARDBI......
  • ftk学习记(多窗口篇)
      在上周末的博客中,我们谈到了listview,今天可以看看效果图如何。  如果大家细心一点,可以发现list中的item有点差异,有兴趣的朋友可以思考一下原因是什么,其实可以代......
  • CF1610H Squid Game
    题面传送门首先定\(1\)为根节点,然后我们发现,如果全部的限制都是弯的,也就是\(x_i\)与\(y_i\)均不是两个点的LCA,则直接选择一个根节点就可以解决。然后如果全部限制都是直......
  • ubuntu双系统+NVIDIA+cuda驱动安装+bios grub一条龙踩坑
    目录ubuntu双系统+NVIDIA+cuda驱动+grub一条龙踩坑ubuntu+windows双系统时间设置修改启动时默认进入的系统ubuntu内部NVIDIA驱动+cuda系统启动时和安装cuda时可能遇到的坑u......
  • 戴尔bios设置
    更多黑苹果经验分享请前往魏叔黑果网~......
  • 主板启动BIOS热键
    组装机主板 品牌笔记本 品牌台式机主板品牌 启动热键 笔记本品牌 启动热键 台式机品牌 启动热键华硕主板 F2、Del或F12 联想笔记本 F12 联想台式机 F12技嘉主板 F12 ......
  • 多窗口切换操作
    多窗口切换操作案例:打开网站主页,然后打开主页的链接详情页面,再回到网络主页打开另一个链接详情页面fromseleniumimportwebdriverfromtimeimportsleepdriver=we......
  • BIOS三种硬盘模式
    文章目录​​IDE模式​​​​RAID模式​​​​AHCI模式​​IDE模式IDE表示硬盘的传输接口,我们常说的IDE接口,也叫ATA(AdvancedTechnologyAttachment)接口,现在PC机使用的硬盘......
  • 速记MBR硬盘,BIOS安装的Win7,EFI安装Ubuntu后如何引导双系统
    前言本文没有图,截图不方便,虚拟机复现可以但是不想开本以为折腾实在不行了,用BIOS启动重装一次Ubuntu环境MBR硬盘EFIWin7拓展分区SwapEFIbyUbuntuUbuntu......
  • Selenium4+Python3系列(五) - 多窗口处理之句柄切换
    写在前面感觉到很惭愧呀,因为居然在Selenium+Java系列中没有写过多窗口处理及句柄切换的文章,不过也无妨,不管什么语言,其思路是一样的,下面我们来演示,使用python语言来实现窗......