zoukankan      html  css  js  c++  java
  • 汇编学习--第十七天

    检测点15.1

    (1)

    pushf

    call dword ptr ds:[0]

    (2)

    设置int 9中断例程的地址的指令有两个部分:

    ;设置新int9中断例程入口地址
    mov word ptr es:[9*4],offset int9
    mov es:[9*4+2],cs
    ;恢复原来int9中断例程入口地址
    mov ax,0
    mov es,ax
    push ds:[0]
    pop es:[9*4]
    push ds:[2]
    pop es:[9*4+2]

    在执行指令期间可能发生键盘中断,引发错误的地址执行,也就是IF寄存器可能为1,所以只要我们在执行这两段指令之间,令IF=0,即可保证程序正确。

    cli
    mov word ptr es:[9*4],offset int9
    mov es:[9*4+2],cs
    sti
    cli
    mov ax,0
    mov es,ax
    push ds:[0]
    pop es:[9*4]
    push ds:[2]
    pop es:[9*4+2]
    sti

    15.5 安装新的int 9中断例程

    在DOS下,按F1键后改变当前屏幕的显示颜色

    assume cs:code
    stack segment
        db 128 dup (0)
    stack ends
    code segment
    start:
        ;栈段地址
        mov ax,stack
        mov ss,ax
        mov sp,128
        
        ;将新中断例程保存到0:204h
        push cs
        pop ds
        mov ax,0
        mov es,ax
        
        mov di,204h
        mov si,offset int9
        mov cx,offset int9end-offset int9
        cld
        rep movsb
        
        ;原int 9中断向量表中的入口地址保存到0:200h~203h
        push es:[9*4]
        pop es:[200h]
        push es:[9*4+2]
        pop es:[202h]
        
        ;设置新int9中断例程入口地址
        cli
        mov word ptr es:[9*4],204h
        mov word ptr es:[9*4+2],0
        sti
        
        mov ax,4c00h
        int 21h
        
        ;新中断例程
    int9:
        push ax
        push bx
        push es
        push cx
        ;从60端口读出键盘的输入
        in al,60h
        
        pushf
        call dword ptr cs:[200h]
    
        cmp al,3bh;判断是否按下F1
        jne int9ret
        
        mov ax,0b800h
        mov es,ax
        mov bx,1
        mov cx,2000;一屏幕4000字节
    s:
        inc byte ptr es:[bx]
        add bx,2
        loop s
        
    int9ret:
        pop cx
        pop es
        pop bx
        pop ax
        iret
    int9end:nop
        
    code ends
    end start

    实验15 安装新的int 9中断例程

    assume cs:code
    stack segment
        db 128 dup (0)
    stack ends
    code segment
    start:
        mov ax,stack
        mov ss,ax
        mov sp,128
    
        ;将中断例程写到0:204h
        push cs
        pop ds
        
        mov ax,0
        mov es,ax
        
        mov cx,offset int9end-offset int9
        mov si,offset int9
        mov di,204h
        cld
        rep movsb
        
        ;将原int 9中断例程入口地址保存到0:200h
        push es:[9*4]
        pop es:[200h]
        push es:[9*4+2]
        pop es:[202h]
        
        ;将新的中断例程入口地址写入中断向量表
        cli
        mov word ptr es:[9*4],204h
        mov word ptr es:[9*4+2],0
        sti
        
        mov ax,4c00h
        int 21h
        
    int9:
        push ax
        push bx
        push cx
        push es
        ;从端口读取键盘数据
        in al,60h
        
        ;调用原来的int 9中断例程,此时CS=0
        pushf
        call dword ptr cs:[200h]
        
        ;比较是否收到A键值
        cmp al,9eh
        jne int9ret
        
        ;显示一屏幕A
        mov ax,0b800h
        mov es,ax
        mov bx,0
        mov cx,2000
    s:
        mov byte ptr es:[bx],'A'
        add bx,2
        loop s
    int9ret:
        pop es
        pop cx
        pop bx
        pop ax
        iret
    
    int9end:nop
    code ends
    end start

    第16章 直接定址表

    16.1 描述了单元长度的标号

    assume cs:code
    code segment
        a:    db 1,2,3,4,5,6,7,8
        b:    dw,0
    start:
        mov si,offset a
        mov bx,offset b
        mov cx,8
    s:
        mov al,cs:[si]
        mov ah,0
        add cs:[bx],ax
        inc si
        loop s
        
        mov ax,4c00h
        int 21h
    code ends
    end start

    在上面的代码中,a,b仅仅代表了内存单元的地址

    assume cs:code
    code segment
        a    db 1,2,3,4,5,6,7,8
        b    dw 0
    start:
        mov si,0
        mov cx,8
    s:
        mov al,cs:[si]
        mov ah,0
        add b,ax
        inc si
        loop s
        
        mov ax,4c00h
        int 21h
    code ends
    end start

    在上面代码中,a,b是同时描述了内存地址和单元长度,例如:a表示,地址code:0开始,以后的内存单元都是字节单元。

    检测点 16.1

    assume cs:code
    code segment
        a    dw 1,2,3,4,5,6,7,8
        b    dd 0
    start:
        mov si,0
        mov cx,8
    s:
        mov ax,a[si]
        add word ptr b[0],ax
        adc word ptr b[2],0
        add si,2
        loop s
        
        mov ax,4c00h
        int 21h
    code ends
    end start

    16.2 在其他段中使用数据标号

    后面加有“:”的地址标号,只能在代码段中使用。

    要在代码段中直接使用数据标号访问数据,则需要用伪指令assume将标号所在段和一个寄存器联系起来。

    assume cs:code,ds:data
    data segment
        a db 1,2,3,4,5,6,7,8
        b dw 0
    data ends
    code segment
    start:
        mov ax,data
        mov ds,ax
        
        mov si,0
        mov cx,8
    s:
        mov al,a[si]
        mov ah,0
        add b,ax
        inc si
        loop s
        
        mov ax,4c00h
        int 21h
    code ends
    end start
    data segment
        a db 1,2,3,4,5,6,7,8
        b dw 0
        c dw a,b
    data ends
    
    相当于:
    
    data segment
        a db 1,2,3,4,5,6,7,8
        b dw 0
        c dw offset a,offset b
    data ends
    data segment
        a db 1,2,3,4,5,6,7,8
        b dw 0
        c dd a,b
    data ends
    
    相当于
    
    data segment
        a db 1,2,3,4,5,6,7,8
        b dw 0
        c dd offset a,seg a,offset b,seg b
    data ends

    seg 为获得某一标号的段地址

    检测点 16.2

    mov ax,data

    mov ds,ax

    16.3 直接定址表

    编写子程序,以十六进制形式在屏幕中间显示给定的字节数据

    assume cs:code,ds:data
    data segment
        table db '0123456789ABCDEF'
    data ends
    code segment
    start:
        mov ax,data
        mov ds,ax
        mov al,0BCH
        ;高8位和低8位分离
        mov ah,al
        mov cl,4
        shr ah,cl
        and al,00001111b
        
        mov bx,0b800h
        mov es,bx
        mov di,12*160+40*2
        ;在table中找到对应位置,显示
        mov bl,ah
        mov bh,0
        mov ah,table[bx]
        mov es:[di],ah
        
        mov bl,al
        mov bh,0
        mov al,table[bx]
        mov es:[di+2],al
        
        mov ax,4c00h
        int 21h
    code ends
    end start

    显示sin(x)的值

    assume cs:code
    code segment
    start:
        mov al,90;度数
        call showsin
        
        mov ax,4c00h
        int 21h
    
    showsin: 
        jmp short show
        table dw ag0,ag30,ag60,ag90,ag120,ag150,ag180
        ag0   db '0',0
        ag30  db '0.5',0
        ag60  db '0.866',0
        ag90  db '1',0
        ag120 db '0.866',0
        ag150 db '0.5',0
        ag180 db '0',0
    
    show:
        push bx
        push es
        push di
    
        mov bx,0b800h
        mov es,bx
        mov di,160*12+40*2
        
        mov ah,0       
        mov bl,30      
        div bl
        mov bl,al      
        mov bh,0
        add bx,bx     
        mov bx,cs:table[bx]      
    
    shows:
        mov ah,cs:[bx]     
          cmp ah,0          
        je showret
          mov es:[di],ah     
        inc bx            
        add di,2
        jmp short shows
    
    showret:
        pop di
        pop es
        pop bx
        ret
    code ends
    end start

  • 相关阅读:
    maven项目启动报错
    maven环境变量配置
    jdk版本升级 eclipse启动失败
    jdk10 环境变量配置
    Invalid bound statement 无效的绑定 的解决办法!
    【Java】-NO.16.EBook.4.Java.1.004-【疯狂Java讲义第3版 李刚】- 内部类
    【Java】-NO.14.Java.4.Java.1.001-【Java JUnit 5 】-
    【Java】-NO.13.Java.1.Foundation.1.001-【Java IO】-
    【设计模式】用追MM来解释23种设计模式,转
    【Linux】-NO.8.Linux.4.Command.1.001-【Common Command】-
  • 原文地址:https://www.cnblogs.com/Mayfly-nymph/p/11247730.html
Copyright © 2011-2022 走看看