1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
assume cs:code
 
code segment
	mov ax, 04c00h
	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
 
code ends
end start

说这个程序奇怪,是因为用来结束程序并返回的两个语句:

	mov ax, 04c00h
	int 21h

没有放在程序结束处,而是放在的代码段的起始位置,更甚,由于程序是从start开始执行的,似乎永远不会执行到这两行,程序也永远不会结束。但是这个程序却能正常结束,而且是由我们的这两行代码来结束执行的。
其中的猫腻就在于短转移指令jmp short s1。jmp指令是用来更改寄存器CS:IP来实现程序的转移的,汇编语言中一般是以标号来指明跳转的目的地址的。对于长转移指令,例如jmp dword ptr ds:[0],CPU确实是以目标地址的段基址和段内偏移来修改CS:IP的。但是对于短转移来说,却是利用当前IP与目标地址之间的的偏移量来确定的。上例中,执行jmp short s1时,IP指向下一条指令nop,与目标地址s1之间偏移量为10:

   CS:IP     机器码             汇编指令(编译器将标号进行了替换)
0B80:0018 B80000        MOV     AX,0000    ;s1
0B80:001B CD21          INT     21
0B80:001D B80000        MOV     AX,0000
0B80:0020 EBF6          JMP     0018           ; jmp short s1
0B80:0022 90              NOP

s1与s2之间的机器指令整好是10个字节,-10(向低地址方向转移)的补码是0xF6h,看汇编指令jmp short s1对应的机器指令EBF6,发现什么了吗?F6就指明了偏移量!
再回到正题,程序中将jmp short s1原封不动地复制到了s处,当程序执行到s处时,向前跳转10个字节,恰好是本文开始提到的那两条用来结束程序的指令!
其实,这个程序没有任何的实际意义,但却能加深我对汇编指令内部机理的理解。

Tags: ,,.
你好!除了代码,此处没有多少原创之物,皆为本人搜集、整理、总结之记录与心得,欢迎转载分享!转载时请尽量注明出处,将不胜感激。祝你健康、快乐!
Home

RFC: Request For Comments. Orz..

Be the first to comment on this entry.

Name(required)
Mail (required),(will not be published)
Website(recommended)