|
主题 : : 直接定址表,实验16 [待解决] |
回复[ 2次 ]
点击[ 154次 ] | |
|
|
|
|
[帖 主]
[ 发表时间: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************************* | | |
|
|
|
|
[第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 | | |
|
|
|
|
[第2楼]
[ 回复时间:2011-11-14 19:26 ]
[引用]
[回复]
[ top ] | |
荣誉值:405
信誉值:0
注册日期:2008-01-19 14:51 |
问题解决了就好。这个程序的问题比较不太好找。需要我们很扎实很深入地掌握安装,偏移地址等问题。 | | |
|