中断过程解释

在8086汇编中有一个事情就是中断,比如说在div指令时可能会引发除0异常,这个时候就会转到中断处理程序去执行,比如说调用

int 0h

指令,那么背后的原理是啥?
事情是这样的,假设我们现在调用了int 0h指令,系统会首先把cs,ip依次压入栈,可能还有其它需要保存的参数,这里只关注cs和ip
到(8086系统)以0000h为段起始地址找中断向量表,这个表里存放了多种中断程序的入口地址,也称为中断向量,这个找的过程:比如说是第N号中断,那么4个字节为一组(存放的是一组中断向量)然后去0000:N4的位置就可以
这里注意0000:N
4是偏移地址,0000:N*4+2是段基址
这个地址的组成是:高2个字节为段基址,低2个字节为偏移地址,由该地址就可以找到处理程序的入口,然后进行执行,执行完毕之后恢复psw(标志寄存器)和pc(cs和ip)
现在做一个有意思的事情:改变中断向量入口,把原本应该报溢出错误的东西换成我们自己的代码。
怎么做呢?很简单,把我们程序的入口放在0000:0000(假设调用int 0h)也就是改变对应内存存放的地址,这样的话就可以调用我们自己写的代码了
附代码,这里面使用了中断处理程序做了一个循环,要尤其注意各个寄存器对应的默认段基址寄存器是啥
比如说si对应的是ds寄存器,di对应的是es寄存器(扩展寄存器)bx对应的是ds寄存器,bp对应的是ss寄存器

; multi-segment executable file template.

data segment
    ; add your data here!
    pkey db "press any key...$"   
    count db 1h
ends

stack segment
    dw   128  dup(0)
ends

code segment
start:
; set segment registers:
    mov ax,0
    mov ds,ax
    mov es,ax
      
    mov ds,ax
    mov bx,0  ;得把ds段也放成0
    mov ds:bx+2,cs  ;放段基址
    mov ds:bx,word ptr dzz   ;放偏移地址 
    lea bx,dzz
    mov dx,offset s-offset se
    mov al,40h     
    
    ;mov cx,1
    s:  
    mov ah,2;调用10号中断的2号程序,改变光标位置
    push dx
    mov dl,count;列号
    mov dh,count 
    int 10h
    inc dl
    mov count,dl
    pop dx;这个是打印的数据变量 
    inc al
    int 0H            
    
    se:
    mov ax, 4c00h ; exit to operating system.
    int 21h  
    
    
    dzz:
    mov cx,1
    mov ah,9
    mov bh,0
    mov bl,11001001B
    int 10h 
    cmp al,5Ah
    jz y  ;如果是0不加偏移量,如果不是0加偏移量
    mov bp,sp;这里做出脱裤子放屁的举动是因为sp变量不能取地址
    add [bp],dx;给栈里面的原有偏移值加一个偏移量使得它能够回到s标号位置
    y:
    iret 
    
    dzzend:
    nop

  
    ; wait for any key....    
    mov ah, 1
    int 21h
    
     
ends

end start ; set entry point and stop the assembler.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值