zoukankan      html  css  js  c++  java
  • 汇编语言(王爽)-实验16

    实验 16 编写包含多个功能子程序的中断例程

    安装一个新的 int 7ch 中断例程,为显示输出提供如下功能子程序:

    1. 清屏。
    2. 设置前景色
    3. 设置背景色
    4. 向上滚动一行

    入口参数说明:

    1. 用 ah 寄存器传递功能号:0 表示清屏,1 表示设置前景色,2 表示设置背景色,3 向上滚动一行
    2. 对于 2、3 号功能,用 al 传递颜色值,(al)∈ {0, 1, 2, 3, 4, 5, 6, 7}。

    前提条件 (基础知识)

    要完成这个实验要了解 jmp 和 call 那两章。比方说 call 是让 IP 寄存器加上一个 offset 还是直接把内存单元的内容作为 IP。了解这一点之后就可以了。

    假设我们的中断例程只有一个子程序

    这个实验的难点在于怎么正确找到我们子程序的入口,也就是当我们把我们写的中断例程安装到 0:200h 之后怎么才能找到我们的子程序。

    书里面说过,所有用到标号的地方,那个标号代表的是地址(p94),再进一步来说其实就是那个标号对应的 IP 寄存器的内容。
    所以在 functions 这个标号里面用到的 clear 的意思是 clear 在 code 这个段里面 IP 是多少。
    int7c 放在段的开头,安装程序放在后面。汇编器编译代码之后我们的 clear + 200h 相当于 offset clear + 200h。
    这里的意思不是说编译器做了 clear 替换成 offset clear,而是我们的 clear 所代表的 IP 恰好就是我们的 offset clear。

    对于普通的程序,我们运行的时候第一条指令的 (IP)= 0。安装之后我们把它拷贝到了 0:200h。相当于起点从 0 变成了 200h,
    所以要定位到 clear 需要用 clear + 200h。

    我们的程序安装之后放在 0:200h 的那个地方,我们用 call word ptr [addr] 的意思是吧 [addr] 的内容作为 IP。
    我们要找 clear + 200h,要从 0:200h 那个地方找。当中断例程执行时 (CS) = 0,我们的索引应该是 [200h + offset functions + 功能号 * 2]

    程序的设计思想是进入中断例程之后跳转到 dispatch,来决定调用哪一个 function。

    assume cs:code
    
    code segment
    int7c:
        jmp short dispatch
    functions:
        dw clear + 200h
    
    dispatch:
    
        call word ptr cs:functions[0+200H]  ; 书的p273,当中断例程执行时 (CS) = 0
    
        iret
    
    clear:
        push ax
        push es
        push cx
        push di
    
        mov ax,0b800h
        mov es,ax
        mov cx,80*24
        mov di,0
    
        clear_fill:
            mov byte ptr es:[di],' '
            add di,2
            loop clear_fill
        
        pop di
        pop cx
        pop es
        pop ax
        ret
    endOfInt7c:
        nop
    
    start:
        ; install
        mov ax,0
        mov es,ax
        mov ax,cs
        mov ds,ax
    
        mov si,offset int7c
        mov di,200H
    
        mov cx,offset endOfInt7c - offset int7c
        cld
        rep movsb
    
        ; setup 7ch * 4 and 7ch * 4 + 2
        mov word ptr es:[7ch * 4],200H
        mov word ptr es:[7ch * 4 + 2],0H
    
        ; test
        int 7ch
    
        ; return
        mov ax,4c00h
        int 21h
    
    
    code ends
    end start
    

    完整的程序

    子程序的实现参考书上的,对于效果不是特别理想。但是重点在于实现中断子程序的功能。

    assume cs:code
    
    code segment
    int7c:
        jmp short dispatch
    functions:
        dw clear + 200h, setFrontColor + 200h, setBackgroundColor + 200h, scroll + 200h
    
    dispatch:
        push bx
        
        sub bx,bx
        mov bl,ah
        add bx,bx
        call word ptr cs:functions[bx+200H]
    
        pop bx
        iret
    
    clear:
        push ax
        push es
        push cx
        push di
    
        mov ax,0b800h
        mov es,ax
        mov cx,80*24
        mov di,0
    
        clear_fill:
            mov byte ptr es:[di],' '
            add di,2
            loop clear_fill
        
        pop di
        pop cx
        pop es
        pop ax
        ret
    
    setFrontColor:
        push bx
        push cx
        push es
    
        mov bx,0b800h
        mov es,bx
    
        mov bx,1
        mov cx,2000
        setFrontColor_loop:
            and byte ptr es:[bx],11111000b
            or es:[bx],al
            add bx,2
            loop setFrontColor_loop
    
        pop es
        pop cx
        pop bx
        ret
    
    setBackgroundColor:
        push ax
        push bx
        push cx
        push es
    
        mov bx,0b800h
        mov es,bx
        mov cl,4
        shl al,cl
    
        mov bx,1
        mov cx,2000
        setBackgroundColor_loop:
            and byte ptr es:[bx],10001111b
            or es:[bx],al
            add bx,2
            loop setBackgroundColor_loop
    
        pop es
        pop cx
        pop bx
        pop ax
        ret
    
    scroll:
        push bx
        push cx
        push si
        push di
        push es
        push ds
    
        mov bx,0b800h
        mov es,bx
        mov ds,bx
    
        mov si,160
        mov di,0
    
        cld
        mov cx,24
        scroll_loop:
            push cx
            mov cx,160
            rep movsb
            pop cx
            loop scroll_loop
    
        ; clear_last_line
        mov cx,80
        mov si,0
        scroll_clear_loop:
            mov byte ptr [160*24+si],' '
            add si,2
            loop scroll_clear_loop
        
        pop ds
        pop es
        pop di
        pop si
        pop cx
        pop bx
        ret
    endOfInt7c:
        nop
    
    start:
        ; install
        mov ax,0
        mov es,ax
        mov ax,cs
        mov ds,ax
    
        mov si,offset int7c
        mov di,200H
    
        mov cx,offset endOfInt7c - offset int7c
        cld
        rep movsb
    
        ; setup 7ch * 4 and 7ch * 4 + 2
        mov word ptr es:[7ch * 4],200H
        mov word ptr es:[7ch * 4 + 2],0H
    
        mov ah,3
        mov al,2
        ; test
        int 7ch
    
        ; return
        mov ax,4c00h
        int 21h
    
    
    code ends
    end start
    
  • 相关阅读:
    死锁篇
    java线程池
    sql server 多行数据指定字符串拼接
    动态提交 表格
    ABP
    DDD学习
    sql 语句插入数据返回id
    Post方式提交,通过上下文HttpContext,Request[""]获取
    JQ的过滤隐藏
    sql 查询有多少行
  • 原文地址:https://www.cnblogs.com/fnmain/p/15123105.html
Copyright © 2011-2022 走看看