汇编语言do0显示字符串

do0:
    设置 ds:si 指向字符串
    mov ax,0b800h
    mov es,ax
    mov 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

程序写好了,可要显示的字符串放在那里呢?我们看下面的程序

assume cs:code

data segment
 db  "overflow"
data ends

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

   设置中断向量表
   mov ax,4c00h
   in 21h
do0:  mov ax,data
      mov ds,ax
      mov si,0

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

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

do0end:nop
end start

上面的程序,看似合理,可实际上却大错特错。注意,"overflow !”在程序12.2的data段中。程序12.2执行完成后返回,它所占用的内存空间被系统释放,而在其中存放的“overflow!”也将很可能被别的信息覆盖。而do0程序被放到了0:200处,随时都会因发生了除法溢出而被CPU执行,很难保证do0程序从原来程序12.2所处的空间中取得的是要显示的字符串“overflow! "。
因为do0程序随时可能被执行,而它要用到字符串“overflow! ",所以该字符串也应该存放在一段不会被覆盖的空间中。正确的程序如下。

assume cs:code

data segment
 db  "overflow"
data ends

start:
    mov ax,cs
    mov ds,ax
    mov si,offset do0     ;设置ds:si指向源地址
    mov ax,0              
    mov es,ax
    mov di,200h            ;设置es:di指向目的地址
    mov cx,offset do0end-offset do0    ;设置cx的传输长度
    cld                                ;设置传输方向为正
    rep movsb

   设置中断向量表
   mov ax,4c00h
   in 21h
do0:jmp short do0start
   db"overflow!"

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

      mov ax,0b800h
      mov es,ax
      mov 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

在程序中,将“overflow!”放到do0程序中,程序12.3执行时,将标号do0到标号do0end之间的内容送到0000:0200处。 注意,因为在do0程序开始处的“overflow!”不是可以执行的代码,所以在" overflow !”之前加上一条jmp指令,转移到正式的do0程序。当除法溢出发生时,CPU执行0:200处的jmp指令,跳过后面的字符串,转到正式的do0程序执行。 do0程序执行过程中必须要找到“overflow! ",那么它在哪里呢?首先来看段地址,"overflow!”和do0的代码处于同一个段中,而除法溢出发生时,CS中必然存放do0的段地址,也就是“overflow!”的段地址;再来看偏移地址,0:200处的指令为jmp shortdo0start,这条指令占两个字节,所以“overflow!”的偏移地址为202h


发布日期:

所属分类: 易语言 标签: