|
主题 : : 实验13代码 [待解决] |
回复[ 9次 ]
点击[ 843次 ] | |
|
|
|
|
[帖 主]
[ 发表时间:2011-01-21 16:26 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-01-02 12:37 |
assume cs:code
data segment
db 'TEST SUCCESS', 0
data ends
code segment
;----------------------------------------------------------
;类型:中断例程
;功能:显示一个用0结束的字符串
;参数:dh=行号 dl=列号 cl=颜色 ds:si=字符串首地址
;----------------------------------------------------------
show_str:
push es
push ax
push bx
push si
mov ax, 0b800h ;bx指向显存地址
mov es, ax
mov al, 0a0h
mul dh
mov bx, ax
mov al, 2
mul dl
add bx, ax
mov ah, cl ;保存颜色
show: ;向显存中复制字符串
mov al, [si]
cmp al, 0
je ok
mov es:[bx], ax
add bx, 2
inc si
jmp show
ok:
pop si
pop bx
pop ax
pop es
iret
;----------------------------------------------------------
;功能:程序入口
;----------------------------------------------------------
main:
mov ax, cs ;ds:si=复制的源地址
mov ds, ax
mov si, offset show_str
xor ax, ax ;es:di=复制的目标地址
mov es, ax
mov di, 200h
mov cx, offset main - offset show_str ;cx=复制长度
cld ;复制代码
rep movsb
mov ds, ax ;修改中断向量
mov ds:[7ch * 4], 200h
mov ds:[7ch * 4 + 2], ax
mov ax, data ;测试中断
mov ds, ax
xor si, si
mov dh, 12
mov dl, 30
mov cl, 1100b
int 7ch
mov ax, 4c00h ;退出
int 21h
code ends
end main | | |
|
|
|
|
[第1楼]
[ 回复时间:2011-01-21 16:26 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-01-02 12:37 |
assume cs:code
data segment
db 'TEST SUCCESS', 0
data ends
code segment
;----------------------------------------------------------
;类型:中断例程
;功能:完成loop指令功能
;参数:bx=位移 cx=循环次数
;----------------------------------------------------------
do_loop:
dec cx
jcxz ok
push bp
mov bp, sp
add [bp + 2], bx
pop bp
ok:
iret
;----------------------------------------------------------
;功能:程序入口
;----------------------------------------------------------
main:
mov ax, cs ;ds:si=复制的源地址
mov ds, ax
mov si, offset do_loop
xor ax, ax ;es:di=复制的目标地址
mov es, ax
mov di, 200h
mov cx, offset main - offset do_loop ;cx=复制长度
cld ;复制代码
rep movsb
mov ds, ax ;修改中断向量
mov ds:[7ch * 4], 200h
mov ds:[7ch * 4 + 2], ax
mov ax, 0b800h ;测试中断
mov es, ax
mov di, 160 * 12
mov bx, offset s - offset se
mov cx, 80
s:
mov byte ptr es:[di], '!'
inc di
mov byte ptr es:[di], 1100b
inc di
int 7ch
se:
mov ax, 4c00h ;退出
int 21h
code ends
end main | | |
|
|
|
|
[第2楼]
[ 回复时间:2011-01-21 16:26 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-01-02 12:37 |
assume cs:code
code segment
s1:
db 'Good,better,best,', '$'
s2:
db 'Never let it rest,', '$'
s3:
db 'Till good is better,', '$'
s4:
db 'And better,best.', '$'
s:
dw offset s1, offset s2, offset s3, offset s4
row:
db 2, 4, 6, 8
main:
mov ax, cs
mov ds, ax
mov bx, offset s
mov si, offset row
mov cx, 4
ok:
mov bh, 0 ;第0页
mov dh, [si] ;____行号
mov dl, 0 ;列号
mov ah, 2 ;置光标
int 10h
mov dx, [bx] ;____指向目标字符串
mov ah, 9
int 21h
add bx, 2 ;____
inc si ;____
loop ok
mov ax, 4c00h ;退出
int 21h
code ends
end main | | |
|
|
|
|
[第3楼]
[ 回复时间:2011-10-05 20:27 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-10-05 20:01 |
感觉第一个楼主实现的挺好的,但是怎么没有堆栈段呢??,没有堆栈段程序连接怎么能通过??,还有一个问题是:我们可不可以通过两个相互独立的程序,一个程序装载中断例程(如:loadint),一个程序调用中断(如revokeint),单独运行两个程序,当loadint程序运行完后在0:200出已经保存了该中断例程,并且7ch是他的中断类型码,之后我们在revokeint程序中调用中断例程int 7ch,理论上这好像会成立,只要连个程序是在同一次开机情况下运行!,但为什么这样似乎不行呢??,系统好像会在程序运行后自动将中断向量表恢复到原样???,希望大侠分析分析! | | |
|
|
|
|
[第4楼]
[ 回复时间:2011-10-05 21:24 ]
[引用]
[回复]
[ top ] | |
荣誉值:118
信誉值:0
注册日期:2011-07-07 22:59 |
在实模式下不会,但是你的安装程序在退出时得把被安装的部分留在内存中,这个可以用21h中断的31h功能。 | | |
|
|
|
|
[第5楼]
[ 回复时间:2011-10-06 10:26 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-10-05 20:01 |
是实模式下系统不会自动恢复中断向量表吗?windows xp下怎么进入实模式呢?? | | |
|
|
|
|
[第6楼]
[ 回复时间:2011-10-06 16:05 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-03-29 22:13 |
|
|
|
|
|
[第7楼]
[ 回复时间:2011-10-06 22:25 ]
[引用]
[回复]
[ top ] | |
荣誉值:118
信誉值:0
注册日期:2011-07-07 22:59 |
是实模式下系统不会自动恢复中断向量表吗?windows xp下怎么进入实模式呢??
------------------
回复:不会,所以在程序中要先保存原中断入口,退出时再恢复。实模式下你想怎么样都可以,但是想从winxp转到实模式是需要很深的功力,其实从实模式转保护模式就调用一个中断就行,但是反过来就很麻烦。 | | |
|
|
|
|
[第8楼]
[ 回复时间:2013-05-12 17:15 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-01-02 12:37 |
|
|
|
|
|
[第9楼]
[ 回复时间:2013-05-12 17:15 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-01-02 12:37 |
assume cs:code, ds:data, ss:stack
data segment
db 'welcome to masm!', 0
data ends
stack segment
db 040h dup (0)
stack ends
code segment
start:
mov ax, stack ; 设置堆栈
mov ss, ax
mov sp, 040h
mov ax, cs
mov ds, ax
mov si, offset show_string
call code_copy ; 安装中断函数
mov bx, 07ch
call set_interrupt_address ; 设置中断向量
mov dh, 0ah ; 测试代码
mov dl, 0ah
mov cl, 00000010b
mov ax, data
mov ds, ax
xor si, si
int 07ch
mov ax, 04c00h ; 程序退出
int 021h
;--------------------------------------------------------
; 功能 - 显示一个以0结束的字符串
; 参数 - (dh) = 行号
; (dl) = 列号
; (cl) = 颜色
; (ds:si) = 字符串首地址
;--------------------------------------------------------
show_string:
push es
push ax
push si
push di
mov ax, 0b800h
mov es, ax
mov al, 0a0h
mul dh
mov di, ax
mov al, 02h
mul dl
add di, ax
mov ah, cl
show_string_copy:
mov al, ds:[si]
test al, al
jz show_string_done
mov es:[di], ax
inc si
add di, 2
jmp show_string_copy
show_string_done:
pop di
pop si
pop ax
pop es
iret
;--------------------------------------------------------
; 功能 - 将中断程序安装到0:200处
; 参数 - (ds:si) = 中断过程的起始地址
;--------------------------------------------------------
code_copy:
push es
push ax
push si
push di
xor ax, ax
mov es, ax
mov di, 0200h
code_copy_again:
mov al, ds:[si]
mov es:[di], al
cmp al, 0cfh ; 遇到iret则停止复制
jz code_copy_done
inc si
inc di
jmp code_copy_again
code_copy_done:
pop di
pop si
pop ax
pop es
ret
;--------------------------------------------------------
; 功能 - 设置中断向量
; 参数 - (bx) = 中断号
;--------------------------------------------------------
set_interrupt_address:
push ds
push bx
push cx
xor cx, cx
mov ds, cx
mov cl, 2
shl bx, cl
mov word ptr ds:[bx].0, 0200h
mov word ptr ds:[bx].2, 0h
pop cx
pop bx
pop ds
ret
code ends
end start | | |
|