在这里假设你已经有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
“`