. : : Assembly Language : : .  |  首页  |  我提出的问题  |  我参与的问题  |  我的收藏  |  消息中心   |  游客  登录  | 
刷新 | 提问 | 未解决 | 已解决 | 精华区 | 搜索 |
  《汇编语言》论坛 ->外中断
  管理员: assembly   [回复本贴] [收藏本贴] [管理本贴] [关闭窗口]
主题 : :  直接定址表,实验16  [待解决] 回复[ 2次 ]   点击[ 154次 ]  
linguangliang
[帖 主]   [ 发表时间:2011-10-07 19:27 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2011-10-05 20:01
data        segment
        one_str                db        'welcome to assmbley word!'
        two_str                db        'i will try my best to do it!'
        three_str        db        'so i trust me will succeed!'
        four_str        db        'wait for my good information!'
        vit                 db        ?
        off        dw        one_str,two_str,three_str,four_str,vit
        err_str        db        'input improper!$'
data        ends
  
stack1        segment        stack
    dw        100h        dup(?)
stack1        ends    
    
code        segment
    assume cs:code,ss:stack1,ds:data
start:
    mov ax, data
    mov ds, ax
    mov ax, 0b800h                ;获得显存地址        
    mov es, ax
    mov di, 30*2        ;每行在30列处显示 
    mov ax, di
    mov bp, 0
    ;像显存写入4行
    mov cx, 4        
lop1:
    push cx
    mov si, 0
    mov bx, ds:off[bp]
    mov cx, ds:off[bp+type off] 
    sub cx, ds:off[bp]
sublop1:
    mov dh, [bx][si]
    mov byte ptr es:[di], dh
    add di, 2
    inc si
    loop sublop1
    add ax, 160
    mov di, ax
    add bp, type off
    pop cx
    loop lop1
    ;装入7ch号中断
    mov ax, 0
    mov es, ax
    push es:[7ch*4]
    push es:[7ch*4+2]
    
    mov word ptr es:[7ch*4], offset int7ch
    mov word ptr es:[7ch*4+2], seg int7ch
    

    ;ah保存功能选择(0-4,0:刷屏,1:设置前景色,2:设置背景色,3:上翻一行)
    ;al保存颜色属性(前景色和背景色0-7,只有1,2号功能才需要al)
lop2:
    mov ah, 1
    int 21h
    mov dl, al
    cmp dl, '0'
    je  nocolor
    jb  exit
    cmp dl, '3'
    je  nocolor
    ja  exit
    ;先忽略任意键(主要是为了忽略分隔符)
    mov ah, 1
    int 21h
    mov ah, 1
    int 21h
    cmp al, '0'
    jb  exit
    cmp al, '7'
    ja  exit
   
nocolor: 
    sub dl, 30h
    sub al, 30h
    mov ah, dl
    int 7ch                ;得到输入参数后调用自写7ch号中断
    loop lop2
        jmp quit
exit:
    mov dx, offset err_str
    mov ah, 9
    int 21h
quit:
    pop es:[7ch*4+2]
    pop es:[7ch*4]
    mov ah, 1
    int 21h
    mov ah, 4ch
    int 21h
;自写7ch号中断,输入参数如下:
;ah保存功能选择(0-4,0:刷屏,1:设置前景色,2:设置背景色,3:上翻一行)
;al保存颜色属性(前景色和背景色0-7,只有1,2号功能才需要al)
int7ch        proc
    table        dw        sub1,sub2,sub3,sub4
    push es
    push di
    push ds
    push si
    push cx
    push ax
    push bx 
    
    mov ax, 0b800h
    mov es, ax
    mov di, 0
    mov bh, 0
    mov bl, ah 
    add bx, bx
    jmp  word ptr cs:table[bx]
    ;刷屏
sub1:
        mov cx, 2000        ;显存模式80*25
sub1lop:
    mov byte ptr es:[di], ' '
    add di, 2
    loop sub1lop
    jmp int7chiret
    ;设置前景色
sub2:
    mov cx, 2000
sub2lop:
    and byte ptr es:[di+1], 11111000b
    or byte ptr es:[di+1], al
    add di, 2
    loop sub2lop
    jmp int7chiret
    ;设置背景色
sub3:  
    mov cl, 4
    shl al, cl
    mov cx, 2000
sub3lop:
    and byte ptr es:[di+1], 10001111b
    or byte ptr es:[di+1], al
    add di, 2
    loop sub3lop
    jmp int7chiret
    ;上翻一行
sub4:
    mov ax, 0b800h
    mov ds, ax
    mov si, 160
        mov cx, 24
sub4lop1:
    push cx
    mov cx, 160        ;movsb会自减cx吗?
    cld
    rep movsb
    pop cx
    loop sub4lop1

    mov cx,80 
    mov si,0 
 sub4lop2:
    mov byte ptr [160*24+si],' ' 
    add si,2 
    loop sub4lop2 

int7chiret:
    pop bx
    pop ax
    pop cx
    pop si
    pop ds
    pop di
    pop es
    iret
int7ch        endp
code        ends
    end        start
//我们可以不讲中断例程装入某一系统空闲内存,如0:200h,而是直接在程序改程序装入内存时直接将自写中断例程的入口地址修改7ch中断向量,之后int 7ch,这样在本程序运行期间,该中断历程应该也能运行啊?  希望帮忙看一下上面程序,有错,待改正!
//另一个问题是,是不是系统会自动恢复中断向量表中的中断向量??,用户的修改是不是只在程序运行时有效果?
//上面程序在dos的debug下出现ntvdm cup遇到无效指令错误!,这问题困扰我很久,网上也没找到像样的解释!,望高手赐教!
*********************QQ:583735151*************************
linguangliang
[第1楼]   [ 回复时间:2011-10-12 21:30 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2011-10-05 20:01
问题解决了。出现了两个错误:
1.   mov ax, 0b800h 
    mov es, ax 
//这两条语句修改了功能号ah和颜色属性al
2. 7chint函数开头的数据定义 table        dw        sub1,sub2,sub3,sub4 
前必须加一条转移指令——转移到指令的开始地址,否则,该数据定义会被当成指令处理,这肯定会造成错误.
//改正后程序如下:
data        segment
        one_str                db        'welcome to assmbley word!'
        two_str                db        'i will try my best to do it!'
        three_str        db        'so i trust me will succeed!'
        four_str        db        'wait for my good information!'
        vit                 db        ?
        off        dw        one_str,two_str,three_str,four_str,vit
        err_str        db        'input improper!$'
data        ends
  
stack1        segment        stack
    dw        400h        dup(?)
stack1        ends    
    
code        segment
    assume cs:code,ss:stack1,ds:data
start:
    mov ax, data
    mov ds, ax
    mov ax, 0b800h                ;获得显存地址        
    mov es, ax
    mov di, 30*2        ;每行在30列处显示 
    mov ax, di
    mov bp, 0
    ;像显存写入4行
    mov cx, 4        
lop1:
    push cx
    mov si, 0
    mov bx, ds:off[bp]
    mov cx, ds:off[bp+type off] 
    sub cx, ds:off[bp]
sublop1:
    mov dh, [bx][si]
    mov byte ptr es:[di], dh
    add di, 2
    inc si
    loop sublop1
    add ax, 160
    mov di, ax
    add bp, type off
    pop cx
    loop lop1
    ;装入7ch号中断
    mov ax, 0
    mov es, ax
    push es:[7ch*4]
    push es:[7ch*4+2]
    
    mov word ptr es:[7ch*4], offset int7ch
    mov word ptr es:[7ch*4+2], seg int7ch
    

    ;ah保存功能选择(0-4,0:刷屏,1:设置前景色,2:设置背景色,3:上翻一行)
    ;al保存颜色属性(前景色和背景色0-7,只有1,2号功能才需要al)
lop2:
    mov ah, 1
    int 21h
    mov dl, al
    cmp dl, '0'
    je  nocolor
    jb  exit
    cmp dl, '3'
    je  nocolor
    ja  exit
    ;先忽略任意键(主要是为了忽略分隔符)
    mov ah, 1
    int 21h
    mov ah, 1
    int 21h
    cmp al, '0'
    jb  exit
    cmp al, '7'
    ja  exit
   
nocolor: 
    sub dl, 30h
    sub al, 30h
    mov ah, dl
    int 7ch                ;得到输入参数后调用自写7ch号中断
    
    loop lop2
    jmp quit
exit:
    mov dx, offset err_str
    mov ah, 9
    int 21h
quit:
    pop es:[7ch*4+2] 
    pop es:[7ch*4]
    mov ah, 1
    int 21h
    mov ah, 4ch
    int 21h
;自写7ch号中断,输入参数如下:
;ah保存功能选择(0-4,0:刷屏,1:设置前景色,2:设置背景色,3:上翻一行)
;al保存颜色属性(前景色和背景色0-7,只有1,2号功能才需要al)
int7ch        proc
   ;若不跳转,调用中断例程时,系统会将下面数据定义解释为指令,从而造成错误!!
   jmp short proc_start
    table        dw        sub1,sub2,sub3,sub4
 proc_start:
   push es
    push di
    push ds
    push si
    push cx
    push ax
    push bx 
    ;不能用ax作为中转站,因为这样会修改传入参数ah,al !!!!!
    mov bx, 0b800h
    mov es, bx
    mov di, 0
    mov bh, 0
    mov bl, ah 
    add bx, bx
    jmp  word ptr cs:table[bx]
    ;刷屏
sub1:
        mov cx, 2000        ;显存模式80*25
sub1lop:
    mov byte ptr es:[di], ' '
    add di, 2
    loop sub1lop
    jmp int7chiret
    ;设置前景色
sub2:
    mov cx, 2000
sub2lop:
    and byte ptr es:[di+1], 11111000b
    or byte ptr es:[di+1], al
    add di, 2
    loop sub2lop
    jmp int7chiret
    ;设置背景色
sub3:  
    mov cl, 4
    shl al, cl
    mov cx, 2000
sub3lop:
    and byte ptr es:[di+1], 10001111b
    or byte ptr es:[di+1], al
    add di, 2
    loop sub3lop
    jmp int7chiret
    ;上翻一行
sub4:
    mov ax, 0b800h
    mov ds, ax
    mov si, 160
        mov cx, 24
sub4lop1:
    push cx
    mov cx, 160        ;movsb会自减cx吗?
    cld
    rep movsb
    pop cx
    loop sub4lop1

    mov cx,80 
    mov di,0 
 sub4lop2:
    mov byte ptr [160*24+di],' ' 
    add di,2 
    loop sub4lop2 

int7chiret:

    pop bx
    pop ax
    pop cx
    pop si
    pop ds
    pop di
    pop es
    iret
int7ch        endp
code        ends
    end        start
tomato
[第2楼]   [ 回复时间:2011-11-14 19:26 ]   [引用]   [回复]   [ top ] 
荣誉值:405
信誉值:0
注册日期:2008-01-19 14:51
问题解决了就好。这个程序的问题比较不太好找。需要我们很扎实很深入地掌握安装,偏移地址等问题。
需要登录后才能回帖 -->> 请单击此处登录
    Copyright © 2006-2024   ASMEDU.NET  All Rights Reserved