-56- | PC机汇编语言实战精解 | ![]() |
|||||||||||||||||||
main code |
int int endp ends end |
21h 20h main |
;显示字符串 ;结束程序,返回操作系统 ;主过程结束 ;代码段结束 ;进程结束 |
||||||||||||||||||
这个程序是前面给出的PROG3-B的源程序形式,程序中的"START"是一个标号,它表示了指令"MOV DX,OFFSET MESS"的地址,值得注意的是它后面多了一个":",这个冒号是必须的。将这个程序编译成COM文件后我们可以用DEBUG将代码反汇编出来,和PROG3-B作个对比: C:\ASM\>DEBUG PROG9.COM [Enter] | |||||||||||||||||||||
-u100[Enter] 0A3E:0100 0A3E:0102 0A3E:0103 0A3E:0104 0A3E:0105 0A3E:0106 0A3E:0107 0A3E:0108 |
EB10 90 48 65 6C 6C 6F 2C57 |
JMP NOP DEC DB DB DB DB SUB |
0112 AX 65 6C 6C 6F AL,57 | | | | | | | | | | |
0A3E:010A 0A3E:010B 0A3E:010D 0A3E:010E 0A3E:0110 0A3E:0112 0A3E:0115 0A3E:0117 0A3E:0119 |
6F 726C 64 210D 0A24 BA0301 B409 CD21 CD20 |
DB JB DB AND OR MOV MOV INT INT |
6F 0179 64 [DI],CX AH,[SI] DX,0103 AH,09 21 20 |
|||||||||||||
区别是很明显的:字符串本是数据,但DEBUG将它们当成了指令机器码,这是DEBUG不够聪明的地方;最奇怪的是"JMP 0112"下面多了个"NOP",这又是什么呢? "NOP"是一条真正的指令,它不执行任何实际的动作,是一条"空操作"(No Operation)指令。这就让人有些犯迷糊了,源程序中并没有这个指令,为什么编译后却多了这样一个东西?想搞清这个问题,我们就必须先详细讨论和转移指令有关的"短程、近程与远程"的问题。 JMP指令究竟被编译成什么样子?观察PROG9的反汇编形式,可以看到JMP 0112的机器码是"EB 10"两个十六进制数。如果"EB"是"JMP"指令对应的机器码,那么"10"又是什么呢?目的地址"0112"又在何处呢? 如果把目的地址"0112"同指令"NOP"的地址做一次减法,问题就清楚了: 0112H - 0102H=10H "10"是目的地址相对"JMP"后面指令所在位置的偏移量,具体的目的地址并不出现在机器码中,而要由CPU自己算出来。这种情况仅限于"短程"和"近程"转移,远程转移时目的地址将以"段:偏移"的形式出现在机器码中。 对于"短"转移来讲,由于偏移量在-128--+127之间,使用一个字节即可记录偏移量,所以短转移指令仅占两个字节。而近转移的偏移量要用两个字节记录,整个指令要占三个字节。 当使用MASM或TASM编译源程序时,编译程序要对源程序作两遍扫描。由于在源程序中未明确给出"JMP"指令是短程还是近程,所以编译程序在第一遍扫描时就默认"JMP"指令是近程的,并在目标程序中为其保留了三个字节空间。然而在第二遍扫描时编译程序算出其偏移量 |
|||||||||||||||||||||
Copyright © 2004-2015 Reanimator | www.cookmoon.org |