目录 上一页 下一页 下一章

-40- PC机汇编语言实战精解

  我们继续使用"T"命令跟踪RET指令:
-t注意堆栈指针SP寄存器恢复成FFFEH
AX=0161BX=0001CX=0000DX=6131SP=FFFEBP=0000SI=0000DI=0000
DS=0A3EES=0A3ESS=0A3ECS=0A3EIP=0107 NV UP EI PL ZR NA PE CY
0A3E:01073C1BCMP AL,1B
可以看到CPU确实返回到0107处执行CMP指令
  前面我们编写过一些程序用RET指令返回DOS,RET为什么会有这样的功能呢?
  如果在启动DEBUG之后注意观察SP寄存器的初值,就会发现DOS将程序调入内存执行时已事先在堆栈中放入了数据,这个数据就是:
-dfffeDOS预先存于堆栈中的返回地址
0A3E:FFF0                     00 00      ..
  当CPU执行RET指令时,这个"0"将被弹到IP寄存器中,也就是说CPU将从CS:0处继续执行指令。那么在CS:0处有没有指令呢?我们可以把CS:0处的指令"反汇编"出来。在"-"后打入"U0"并回车:
-u0[Enter]
0A3E:0000CD20INT20
0A3E:0002FF9F009ACALLFAR [BX+9A00]
0A3E:0006F0LOCK
0A3E:0007FE1DCALLFAR [DI]
0A3E:0009F0LOCK
0A3E:000A4FDECDI
0A3E:000B038D048AADDCX,[DI+8A04]
.
.
.
  当我们用A命令输入指令时,这些指令都被DEBUG编译成机器码。我们要想通过机器码重新获得指令,就必须"Unassembled"(反汇编),这就是命令码"U"的来历。
  此命令可以将内存中任意位置开始的机器码反汇编成指令,若打入"U100[Enter]",那么DEBUG将把CS:100处开始的指令显示在屏幕上。
  "反"出来的指令和我们当初输入的指令应该是相同的。那些紧挨着逻辑地址后面的16进制数就是指令编译后的机器码。我们可以大概了解一些常用指令对应的机器码是什么,比如"INT"和"CD"之间的关系。
  反汇编的结果真是不可思意,CS:0处竟然有一条"INT 20"指令。为什么会有这样的一条指令呢?
  前面已经提到过,在我们的程序之前,DOS保留了256字节的内存空间安排了一些重要的数据,这个"CD 20"就是DOS打的小埋伏。这是因为在DOS正式成为PC机的标准操作系统之前,已有人编写了一个称为"CP/M-86"的操作系统,遗憾的是这个可怜的软件没能竞争DOS。不过

Copyright © 2004-2015 Reanimator www.cookmoon.org

目录 上一页 下一页 下一章