. : : Assembly Language : : .  |  首页  |  我提出的问题  |  我参与的问题  |  我的收藏  |  消息中心   |  游客  登录  | 
刷新 | 提问 | 未解决 | 已解决 | 精华区 | 搜索 |
  《汇编语言》论坛 ->INT指令
  管理员: assembly   [回复本贴] [收藏本贴] [管理本贴] [关闭窗口]
主题 : :  实验13代码  [待解决] 回复[ 9次 ]   点击[ 843次 ]  
ruder
[帖 主]   [ 发表时间: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
ruder
[第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
ruder
[第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
linguangliang
[第3楼]   [ 回复时间:2011-10-05 20:27 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2011-10-05 20:01
感觉第一个楼主实现的挺好的,但是怎么没有堆栈段呢??,没有堆栈段程序连接怎么能通过??,还有一个问题是:我们可不可以通过两个相互独立的程序,一个程序装载中断例程(如:loadint),一个程序调用中断(如revokeint),单独运行两个程序,当loadint程序运行完后在0:200出已经保存了该中断例程,并且7ch是他的中断类型码,之后我们在revokeint程序中调用中断例程int 7ch,理论上这好像会成立,只要连个程序是在同一次开机情况下运行!,但为什么这样似乎不行呢??,系统好像会在程序运行后自动将中断向量表恢复到原样???,希望大侠分析分析!
chinatree
[第4楼]   [ 回复时间:2011-10-05 21:24 ]   [引用]   [回复]   [ top ] 
荣誉值:118
信誉值:0
注册日期:2011-07-07 22:59
在实模式下不会,但是你的安装程序在退出时得把被安装的部分留在内存中,这个可以用21h中断的31h功能。
linguangliang
[第5楼]   [ 回复时间:2011-10-06 10:26 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2011-10-05 20:01
是实模式下系统不会自动恢复中断向量表吗?windows xp下怎么进入实模式呢??
meizuo
[第6楼]   [ 回复时间:2011-10-06 16:05 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2011-03-29 22:13
楼主你可以尝试用刚学到13章思维去写这个程序。
chinatree
[第7楼]   [ 回复时间:2011-10-06 22:25 ]   [引用]   [回复]   [ top ] 
荣誉值:118
信誉值:0
注册日期:2011-07-07 22:59
是实模式下系统不会自动恢复中断向量表吗?windows xp下怎么进入实模式呢??
------------------
回复:不会,所以在程序中要先保存原中断入口,退出时再恢复。实模式下你想怎么样都可以,但是想从winxp转到实模式是需要很深的功力,其实从实模式转保护模式就调用一个中断就行,但是反过来就很麻烦。
ruder
[第8楼]   [ 回复时间:2013-05-12 17:15 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2011-01-02 12:37
没事复习一下
ruder
[第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
需要登录后才能回帖 -->> 请单击此处登录
    Copyright © 2006-2024   ASMEDU.NET  All Rights Reserved