|
20鱼币
本帖最后由 Ъγ:_小ツ雨oο 于 2015-7-11 20:27 编辑
- ;编程:在屏幕中间依次显示“a”~“z”,并可以让人看清。在显示的过程中,按下'Esc'键后,改变显示的颜色。
- ;完整功能代码:
- assume cs:code
- stack segment
- db 128 dup (0)
- stack ends
- data segment
- dw 0,0
- data ends
- code segment
- start:
- mov ax,stack
- mov ss,ax
- mov sp,128
- mov ax,data
- mov ds,ax
- mov ax,0
- mov es,ax
- push es:[9*4]
- pop ds:[0]
- push es:[9*4+2]
- pop ds:[2] ;将原来的int 9中断例程的入口地址保存在ds:0、ds:2单元中
- mov word ptr es:[9*4],offset int9
- mov es:[9*4+2],cs ;在中断向量表中设置新的int 9中断例程的入口地址
- mov ax,0b800h
- mov es,ax
- mov ah,'a'
- s:
- mov es:[160*12+40*2],ah
- call delay
- inc ah
- cmp ah,'z'
- jna s
- mov ax,0
- mov es,ax
- push ds:[0]
- pop es:[9*4]
- push ds;[2]
- pop es;[9*4+2] ;将中断向量表中int 9中断例程的入口恢复为原来的地址
- mov ax,4c00h
- int 21h
- delay:
- push ax
- push dx
- mov dx,2000h
- mov ax,0
- s1:
- sub ax,1
- sbb dx,0
- cmp ax,0
- jne s1
- cmp dx,0
- jne s1
- pop dx
- pop ax
- ret
- ;------以下为新的int 9中断例程--------------------
- int9:
- push ax
- push bx
- push es
- in al,60h
- pushf
- pushf
- pop bx
- and bh,11111100b
- push bx
- popf
- call dword ptr ds:[0] ;对int指令进行模拟,调用原来的int 9中断例程
- cmp al,1
- jne int9ret
- mov ax,0b800h
- mov es,ax
- inc byte ptr es:[160*12+40*2+1] ;属性增加1,改变颜色
- int9ret:
- pop es
- pop bx
- pop ax
- iret
- code ends
- end start
复制代码
代码我都理解, debug‘ 不能调试 我也知道原因
求执行过程 比如字符a 按这个程序从上到下执行直接就显示出来了根本没 经过 下面的 中断求解 还有 最后的 iret是pop 哪里的cs和ip |
最佳答案
查看完整内容
楼主这么想一下
既然是模拟int指令 那么正常的int指令结束的最后一条指令的iret是是pop哪里的cs和ip呢
肯定是调用int指令时候的这一地址的cs和ip 好返回当前调用int指令的位置
举个例子
0x1000 -> mov ax, 4c00h
0x1003 -> int 21h
类似于这种手动调用中断, 当int调用的时候肯定是去中断向量表里找中断过程函数
等结束的时候 返回的是1003的位置 即哪里调用的中断
这个int9我觉得有点类似于回调函数 时刻带等待着系统去 ...
|