您的位置:首页 > 其它

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

2018-01-07 22:08 477 查看
在这里假设你已经有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 的大小就是  do
4000
0程序所在的内存偏移地址大小
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


“`
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: