这段程序是王爽的《汇编语言程序设计》第二版上的一个问题,当指令执行到 mov cs:[di],ax这句的时候会将标号s2当中的jmp short s1 这句指令复制到 s当中覆盖两个nop,然后当执行标号s0时候跳转到s执行新的程序,然后会跳转到s1然后程序好像最后应该不会正常的退出
其实不然,当执行新的程序即s标号时候其实内部的指令已经不是跳转到s1了是跳转到 地址为0的地方,即执行mov ax ,4c00h 和int 21退出了,
这个就得跟jmp short 指令有关了,这个指令并没有给出跳转的目的地址,而只是跳转的位移,所以当指令的位置换了以后跳转的地方可能会变,此处就变了,下面是我在debug中测试的
assume cs:codesg
codesg segment
mov ax,4c00h
int 21h
start: mov ax,0
s: nop
nop
mov di,offset s
mov si,offset s2
mov ax,cs:[si]
mov cs:[di],ax
s0: jmp short s
s1: mov ax,0
int 21h
mov ax,0
s2: jmp short s1
nop
codesg ends
end start
刚开始的时候的由编译器翻译后的指令
然后执行完076A:0014后下面的指令是:
跳转到地址为076A:0008处,也就是那个新的指令 jmp 0000
然后再执行就是正常的退出了
jmp short
jmp near ptr
jcxz
loop
这些指令都对IP寄存器的修改都是根据位移(转移目的地址和转移起始地址之间的位移)来进行 ,这个应该是在段内转移时候比较好的
这种设计方式有利于程序在内存中的浮动装配(至于为什么会浮动呢,这得了解操作系统的相关的程序的装入的方面的知识还有地址定位的知识了http://blog.csdn.net/kennyrose/article/details/7531718)
这里再总结两个指令
1. jmp word ptr 内存单元 : 从内存单元地址开始处存放着一个字,是转移的目的偏移地址
2. jmp dword ptr 内存单元 : 从内存单元地址处开始存放着两个字,高地址处的字是转移的目的段地址,低地址是转移的目的偏移地址