-42- | PC机汇编语言实战精解 | ![]() |
|||||||||||||||||||
-p | |||||||||||||||||||||
AX=0100 | BX=0000 | CX=002B | DX=0000 | SP=FFEE | BP=0000 | SI=0000 | DI=0000 | ||||||||||||||
DS=0A3E | ES=0A3E | SS=0A3E | CS=0A3E | IP=0102 | NV UP EI PL NZ NA PO NC | ||||||||||||||||
0A3E:0102 | CD21 | INT 21 | |||||||||||||||||||
注意跟踪指令"INT 21"时务必要使用"P"命令。 | |||||||||||||||||||||
-p | |||||||||||||||||||||
a | 输入小写字母"a" | 注意SP寄存器的内容 | |||||||||||||||||||
AX=0161 | BX=0000 | CX=002B | DX=0000 | SP=FFEE | BP=0000 | SI=0000 | DI=0000 | ||||||||||||||
DS=0A3E | ES=0A3E | SS=0A3E | CS=0A3E | IP=0104 | NV UP EI PL NZ NA PO NC | ||||||||||||||||
0A3E:0104 | 9A1F013D0A | CALL 0A3D:011F | |||||||||||||||||||
为了观察这个"CALL"指令的执行情况,这里要使用"T"命令跟踪。 | |||||||||||||||||||||
-t | 请注意SP寄存器 | ||||||||||||||||||||
AX=0161 | BX=0000 | CX=002B | DX=0000 | SP=FFEA | BP=0000 | SI=0000 | DI=0000 | ||||||||||||||
DS=0A3E | ES=0A3E | SS=0A3E | CS=0A3D | IP=011F | NV UP EI PL NZ NA PO NC | ||||||||||||||||
0A3D:011F | 50 | PUSH AX | |||||||||||||||||||
注意观察SP寄存器的变化,此时堆栈中压入了两个数据: | |||||||||||||||||||||
-dfffa | 返回地址的偏移0109 | 返回地址的段0A3E | |||||||||||||||||||
0A3E:FFF0 | 09 01 3E 0A 00 00 | ..>... | |||||||||||||||||||
0A3E:0109就是返回地址,可以看到CPU先将段地址压栈,然后才压入偏移地址。同时执行CALL指令之后不仅IP寄存器有变化,且CS寄存器也发生了变化。对于CALL指令的这种用法,我们称为"远程调用",因为调用后CS寄存器要改变。 | |||||||||||||||||||||
PROG5 -A100 0A3E:0100 JMP 111 0A3E:0102 DB'Hello,World!',0D,0A,24 0A3E:0111 MOV DX,0102 0A3E:0114 MOV AH,09 0A3E:0116 INT 21 0A3E:0118 MOV AX,0000 0A3E:011B JMP AX |
有"远程调用"自然就有"远程返回","RETF(F表示FAR)"指令就是远程返回指令,它可以将事先存入堆栈的返回地址弹到CS:IP中。大家可以自己验证这一点。 在此我们必须仔细谈谈"跨段"转移的问题,这个问题在讲JMP指令时遗留了下来。一般情况下程序的转移分成三类:短程、近程和远程。凡是转移后CS寄存器被改变,即转移发生在两个段之间,那么这样的转移就是远程的;反之若转移后CS寄存器没有改变,即转移发生在一个段内,这样的转移就是近程的;若转移发生在-128-+127范围内,则这种转移就是短程的;短程转移是近程转移的一个特例。 |
||||||||||||||||||||
Copyright © 2004-2015 Reanimator | www.cookmoon.org |