一文读懂除法溢出-使用汇编重定向0号中端(除法错误中断,比如,执行div指令产生的除法溢出)

在这里假设你已经有8086上的汇编经验
老规矩先贴出程序在一步一步的注释讲解;

assume cs:code
start:  mov ax,cs
        mov ds,ax
        mov si,offset do0
        mov ax,0
        mov es,ax
        mov di,200h
        mov cs,offset do0end - offset do0
        cld 
        rep movsb

        mov ax,0
        mov es,ax
        mov word ptr es:[0*4],200h
        mov word ptr es:[0*4+2],0

        mov ax,4c00h
        int 21h

   do0: jmp short do0start
        db "overflow!"

do0start: mov ax,cs
        mov ds,ax
        mov si,202h

        mov ax,0b800h
        mov es,ax
        ov di,12*160 + 36*2

        mov cx,9
    s:  mov al,[si]
        mov es:[di],al
        inc si
        add di,2
        loop s

        mov ax,4c00h
        int 21h


do0end:nop

code ends
end start   

代码注释部分


```assemble
assume cs:code
;首先安装程序  也就是将d0程序复制到中断0指向的代码段中
;一下三行代码的意思就是设置ds:si  指向源代码  之后使用rep movsb  将源代码复制到相应的内存单元
;mov si,offset do0    offset do0 是由编译器获取标号的偏移地址   执行之后si 的大小就是  do0程序所在的内存偏移地址大小
start:  mov ax,cs
        mov ds,ax
        mov si,offset do0

;在中断向量表中有一段内存是没有使用的   这里使用的就是没有使用的0:200h之后的一段内存单元  
        mov ax,0
        mov es,ax
        mov di,200h
        ;获取标号在程序中的位置,由汇编语言处理的符号,功能是取得标号的偏移地址
        ;下面就是借助offset获取程序的大小
        mov cx,offset do0end - offset do0
;cld设置  标志寄存器的df位为0这样在使用  rep movsb的时候就是正向传输  
;std设置df位为1这样在传输的时候就是反向传输
;rep movsb的作用就是将ds:[si]指向的内存单元逐个传递到es:[di]指向的内存单元 然后再执行 inc si  inc di 使用汇编语言解释就是
;解释开始
;  s: mov es:[di],byte ptr ds:[si]  汇编中并不允许这样做  这里只是为了解释下面的语句
;inc si
;inc di
loop s
;结束
        cld 
        rep movsb
;设置中断向量表  也就是将0号中断向量指向安装好程序的段 的内存单元
;0号中断向量表所在的位置为  0:[0*4]到0:[0*4+2]的一段内存单元,所要做的就是因为是大端模式因此按照  
;mov word ptr es:[0*4],200h
;mov word ptr es:[0*4+2],0
的方式存储
        mov ax,0
        mov es,ax
        mov word ptr es:[0*4],200h
        mov word ptr es:[0*4+2],0

        mov ax,4c00h
        int 21h

   do0: jmp short do0start
        db "overflow!"

do0start: mov ax,cs
        mov ds,ax
        mov si,202h  ;设置ds:si指向字符串

        mov ax,0b800h
        mov es,ax
        ov di,12*160 + 36*2  ;设置 es:di指向显存空间的中间位置

        mov cx,9  ;设置cx为字符串长度
    s:  mov al,[si]
        mov es:[di],al
        inc si
        add di,2
        loop s

        mov ax,4c00h
        int 21h


do0end:nop

code ends
end start   

“`

猜你喜欢

转载自blog.csdn.net/andrewgithub/article/details/78998172