8086CPU 读取、指令过程复习
8086CPU 读取执行指令过程的简要描述
1、从CS:IP 指向的内存单元读取指令,读取的指令进入指令缓冲器
2、IP寄存器内的值自动增加,指向下一条指令
3、执行指令,并转到步骤1
- 简而言之就是,先读取、再IP值自动增加、而后执行
检测点10.2
解析
- 走到
call s
时,IP值已经完成自动增加,此时IP=6 - 执行
call s
之后,IP=6 被压入栈 - 执行
pop ax
,使得的 (ax)=6
答案
- AX的值为 0006H
检测点10.3
解析
-
call far ptr s
等价于
push CS
push IP
jmp far ptr s
CS=1000H IP=8H
被依次压入栈
- 跳转到标号s处开始依次执行
- 最终AX=1010H
答案
- AX的值为 1010H
检测点10.4
解析
-
call ax
等价于
push IP
jmp ax
IP=5 被压入栈
(IP)=(ax)=0006H
程序跳转到CS:IP=1000:0006 处开始执行
-
CS:IP=1000:0006 :
mov bp sp
(bp)=(sp)
add ax,[bp]
bp 默认使用的 SS 作为段地址
[bp] 等价于 SS:[bp],现在指向 栈顶
add ax,[bp] 取出 栈顶内容0005H 与 (ax) 相加
AX 0006H
[bp] 0005H
----------------
000BH
十进制的 十一
十六进制的 B
答案
- AX的值为 000BH
检测点 10.5 (1)
call word ptr ds:[0eH]
等价于
push IP
jmp word ptr ds:[0eH]
等价于
push IP
(IP)=(ds:[0eH])
再跳转到 新的 CS:IP 处
push IP
此时 CS:IP 指向从上往下第一条 inc ax
将这个IP称之为 【IP-旧】 压入栈
(IP)=(ds:[0eH])
要用内存单元地址里的内容修改IP的值,
此时 DS==SS,ds:[0eH == ss:[0eh] 正好就是栈顶,
而栈顶正好存着 【IP-旧】
这恰恰造成了不动的结果
IP-新 = IP-旧
程序按照CS:IP去执行,
即将执行的仍旧是从上往下的第一条 inc ax
最终,经过 三次 inc ax,ax的值变成 0003H
- [0eH]中的0eH怎么来的?
mov sp,16
16是十进制数 十六
写成十六进制就是 10H
本质上就是 mov sp,10H
随着后面入栈操作 PUSH IP
使得 (SP)=(SP)-2
16-2=14 写成十六进制就是 0EH
答案
- AX的值为 0003H
检测点 10.5 (2)
解析
-
我的草稿
-
dw 8 dup(0)
使得data段
存着 16个字节的 00H -
mov sp,16
等价于mov sp,10H
mov word ptr ss:[0], offset s
offset s
取出 标号s 所在的 偏移地址,这里假设为 X
mov word ptr ss:[0], offset s
等价于
(ss:[0]) = X
ss 指向 data 段
在data段的 00-01 内存单元放入 【偏移地址 X】
mov ss:[2],cs
在 data段的02-03内存单元放入【CS的值】
call dword ptr ss:[0]
call dword ptr ss:[0]
等价于
push CS
push IP
jmp dword ptr ss:[0]
将 CS 压入栈,也就是存放到 0EH-0FH 内存单元
将 IP 压入栈,也就是存放到 0CH-0DH 内存单元
此时的IP 已经完成自动增加,IP的值为Y,是nop语句的偏移地址
执行 jmp 指令,又等价于设置新的CS和IP值,再跳转到CS:IP
(IP)= SS:[0] = X 低地址是偏移地址
(CS)= SS:[02] = CS 高地址是段地址
相当于,段地址一直没有变过,IP值现在为X,CS:IP指向 标号s
- 标号s 开始的指令
mov ax,offset s
ax的值变为 X (标号s的偏移地址)
sub ax,ss:[0ch]
ss:[0cH] 存着 Y (nop语句的偏移地址)
sub 是减法指令
X-Y 本质就是 nop 语句所占用的内存单元个数
nop语句只占用1个内存单元
X-Y的值为 1,即0001H
AX的值最终为 0001H
mov bx,CS
bx的值变成 CS
sub ss:[0eH]
ss:[0eH] 存着 CS
CS自己减去自己当然等于0,即0000H
BX的值最终为 0000H
答案
- AX 的值为 0001 H
- BX 的值为 0000 H