汇编网首页登录博客注册
unixandlinux的学习博客
博客首页博客互动【做检测题】论坛求助

我的博客

个人首页 |  我的文章 |  我的相册 |  我的好友 |  最新访客 |  文章收藏 |  论坛提问 |  友情链接 |  给我留言  
图片载入中
学习动态
最新评论
最新留言
好友圈
友情链接

[2023-08-27 20:49] 第 17 章 17.3 节示例

第 17 章 17.3 节示例

可运行的完整测试程序如下:

assume cs:code,ds:stack

; 声明字符栈
stack segment
  db 128 dup (0)
stack ends

code segment

start:        mov ax,stack
        mov ds,ax
        mov si,0

        mov dh,8  ; 行号:8
        mov dl,4  ; 列号:4
        call getstr

        mov ax,4c00h
        int 21h

getstr:  push ax

getstrs: mov ah,0  ; 调用 int 16h 中断(参 17.2 节)的 0 号功能
         int 16h        
         cmp al,20h
         jb nochar  ; ASCII 码小于 20h,说明不是字符
         mov ah,0
         call charstack  ; 字符入栈
         mov ah,2
         call charstack  ; 显示栈中的字符
         jmp getstrs

nochar:  cmp ah,0Eh  ; 退格键的扫描码
        je backspace
        cmp ah,1Ch  ; Enter 键的扫描码
        je enter
        jmp getstrs

backspace:  mov ah,1
            call charstack  ; 字符出栈
            mov ah,2
            call charstack  ; 显示栈中的字符
            jmp getstrs

enter:  mov al,0
        mov ah,0
        call charstack  ; 0 入栈
        mov ah,2
        call charstack  ; 显示栈中的字符
        pop ax
        ret

charstack:  jmp short charstart

        table dw charpush,charpop,charshow
        top dw 0  ; 栈顶

charstart:  push bx
            push dx  ; 将存储着行、列信息的 DX 寄存器数据入栈。注意,这不是字符栈
            push di
            push es

            cmp ah,2
            ja sret
            mov bl,ah
            mov bh,0
            add bx,bx
            jmp word ptr table[bx]

sret:    pop es
         pop di
         pop dx
         pop bx
         ret

charpush:  mov bx,top
           mov [si][bx],al  ; 关于 (si) 参见上面的“参数说明”所述
           inc top
           jmp sret

charpop:  cmp top,0
          je sret
          dec top
          mov bx,top
          mov al,[si][bx]
          jmp sret

charshow:  mov bx,0B800h
           mov es,bx

; 添加:调用 BIOS 的 int 10h 中断例程,以定位光标位置
        mov bx,0
        int 10h        

        mov cx,dx  ; 添加:将 DX 寄存器存储的行、列信息转存到 CX 寄存器
        mov al,160
        mov ah,0
        mul dh  ; DH 寄存器存放行号,执行 (al)×(dh) 乘法运算,结果存放在 AX 寄存器中
        mov di,ax
        add dl,dl  ; DL 寄存器存放列号
        mov dh,0
        add di,dx  ; 这时,DI 寄存器将存放着需要在显示缓冲区显示字符的屏幕具体位置

charshows:  cmp bx,top  ; 比较 (bx) 和 top,以判断字符栈是否到达栈顶
            jne noempty
            mov byte ptr es:[di],' '  ; 如果字符栈已经到达栈顶,则在屏幕显示一个空格字符后退出
            mov byte ptr es:[di+1],64  ; 设置字符属性:背景色为红色
            jmp sret

noempty:  mov al,[si][bx]
          mov es:[di],al
          mov byte ptr es:[di+1],2  ; 设置字符属性:绿色字体
          mov byte ptr es:[di+2],' '  ; 在屏幕所显示字符的后一个屏幕位置显示一个空格字符,以表示下一个要显示的字符将会在此位置显示、输出
          mov byte ptr es:[di+3],64  ; 设置字符属性:背景色为红色
          inc bx
          add di,2

; 添加:调用 BIOS 的 int 10h 中断例程,以定位光标位置
; 由于 (bx) 的初始值为 0,而屏幕一行最多容纳 80 个字符,则 (bh)=0,所以无需设置 (bh)
          inc cl  ; 增加一列,以令光标向后移动一列
          mov ah,2
          mov dx,cx
          int 10h        

          jmp charshows

code ends

end start

程序说明:本程序代码添加了利用 BIOS 的 int 10h 中断例程来定位光标(参 13.6 节),所添加的代码均在其注释处写了“添加”字样。
评论次数(0)  |  浏览次数(280)  |  类型(示例演示) |  收藏此文  | 
 
 请输入验证码  (提示:点击验证码输入框,以获取验证码