這段程序是王爽的《彙編語言程序設計》第二版上的一個問題,當指令執行到 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 內存單元 : 從內存單元地址處開始存放着兩個字,高地址處的字是轉移的目的段地址,低地址是轉移的目的偏移地址