第十章
检测点10.5
(1)下面的程序执行后,ax中的数值为多少?(注意:用call 指令的原理来分析,不要再Debug中单步跟踪来验证你的结论。对于此程序,在Debug中但不跟踪的结果,不能代表CPU的实际执行结果。)
原程序
assume cs:code
stack segment
dw 8 dup(0)
stack ends
code segment
start: mov ax, stack
mov ss, ax
mov sp, 16
mov ds, ax
call word ptr ds:[0EH]
inc ax
inc ax
inc ax
mov ax,4c00h
int 21h
code ends
end start
程序分析
- 我们来对比下程序的
机器码
、段地址
、偏移地址
就明白了。
assume cs:code
stack segment
dw 8 dup(0)
stack ends
code segment
start: mov ax, stack ; 读入后IP=3
mov ss, ax ; 读入后IP=5
mov sp, 16 ;读入后IP=8
mov ds, ax ;读入后IP=10 也就是000AH
call word ptr ds:[0EH] ;读入后IP=000EH 十进制14
;CPU执行 call word ptr 内存地址时,相当于
; push IP ,
; jmp word ptr 内存地址
inc ax ; 从图上刚好这行的IP就是000E,所以相当于顺序执行下来了
inc ax
inc ax
mov ax,4c00h
int 21h
code ends
end start
- 最后ax=3
- 如果对读入后
IP
的值有疑问,参考书上2.11 修改CS、IP指令
就知道了。
(2)下面的程序执行后,ax和bx中的数值为多少?
原程序
assume cs:code
data segment
dw 8 dup (0)
data ends
code segment
start: mov ax, data
mov ss, ax
mov sp, 16
mov word ptr ss:[0], offset s
mov ss:[2], cs
call dword ptr ss:[0]
nop
s: mov ax, offset s
sub ax, ss:[0CH]
mov bx, cs
sub bx, ss:[0EH]
mov ax, 4c00h
int 21h
code ends
end start
程序分析
assume cs:code
data segment
dw 8 dup (0)
data ends
code segment
start: mov ax, data ; ax寄存器指向data数据段
mov ss, ax ; 栈段指向data数据段
mov sp, 16 ; 设置栈顶16
mov word ptr ss:[0], offset s ; s段第一条指令给ss:[0]
mov ss:[2], cs ; cs给ss[2]
call dword ptr ss:[0] ; 读入后IP=0019
; call dword ptr 内存单元地址 相当于
; push是从栈顶开始的
; push CS 注意:push之后CS的值就存在ss:[0EH]
; push IP 注意:push之后CS的值就存在ss:[0CH]
; jmp dword ptr 内存单元地址
nop ; nop机器码占一个字节,这条指令不会产生效果
s: mov ax, offset s ; s代码段第一条指令给ax寄存器,该行指令IP=1A
sub ax, ss:[0CH] ; ss:[0CH] 是前面push的IP值 001AH - 0019H = 1H,中间就差的那个nop
mov bx, cs ; (bx) = (ax)
sub bx, ss:[0EH] ; ss:[0EH]是前面push的cs的值,相当于 cs - cs = 0H
mov ax, 4c00h
int 21h
code ends
end start
- 所以最后 ax = 1H,bx=0H。
- 如果对读入后
IP
的值有疑问,参考书上2.11 修改CS、IP指令
就知道了。