1. 检测点 3.1
(1)使用 d 指令查看 0000:0000~0000:001F 的内存值,并写出每条汇编指令执行完后相关寄存器中的值。
-
8086CPU 中的 DS 寄存器用于存放将要访问数据的段地址(CS 用于存放代码地址),mov、sub、add 指令可实现寄存器和内存单元(使用中括号)之间值的操作。如,mov al,[0] 将段地址为 DS、偏移地址为 0 的内存单元数据送入 al 寄存器中,DS 的计算公式同 CS:IP。 -
8086CPU 不支持直接将数据送入段寄存器中,如 mov ds,1000 错误,而需要使用使用其他寄存器周转,如 mov ax,1000 mov ds,ax。
首先,假如使用 d 指令查看 0000:0000~0000:001F 内存单元的值为:
0000:0000 70 80 F0 30 EF 60 30 E2-00 80 80 12 66 20 22 60
0000:0010 62 26 E6 D6 CC 2E 3C 3B-AB BA 00 00 26 06 66 88
每条汇编执行执行完成后相关寄存器中的值为:
指令 | AX | BX | DS |
---|
mov ax,1 | 0001 | 0000 | 0000 | mov ds,ax | 0001 | 0000 | 0001 | mov ax,[0000] | 2662 | 0000 | 0001 | mov bx,[0001] | 2662 | E626 | 0001 | mov ax,bx | E626 | E626 | 0001 | mov ax,[0000] | 2662 | E626 | 0001 | mov bx,[0002] | 2662 | D6E6 | 0001 | add ax,bx | FD48 | D6E6 | 0001 | add ax,[0004] | 2C14 | D6E6 | 0001 | mov ax,0 | 0000 | D6E6 | 0001 | mov al,[0002] | 00E6 | D6E6 | 0001 | mov bx,0 | 00E6 | 0000 | 0001 | mov bl,[000C] | 00E6 | 0026 | 0001 | add al,bl | 000C | 0026 | 0001 |
注:上述黑体部分中,低位的运算没有影响到高位。
(2)内存中的情况如下图: 各寄存器的初值为:CS=2000H、IP=0、DS=1000H、AX=0、BX=0。
① 使用汇编代码写出 CPU 执行的指令序列。 ② 写出 CPU 每条指令执行后,相关寄存器中的数值。 ③ 程序和数据的区别。
- CPU 从 CS:IP 处开始执行指令,执行完每条指令后,IP 的值加上上一条指令的长度。
- 使用 jmp 指令修改 CS:IP 的值,jmp 段地址:偏移地址,如 jmp 2AE3:3 后,CS=2AE3H、IP=0003H,并且 CPU 将从 2AE3:3 处读取指令并执行;或 jmp 某一合法寄存器名,如 jmp AX 后,IP=AX。
CPU 总是从 CS(2000H):IP(0) 处开始执行指令:
指令 | AX | BX | CS | IP | DS |
---|
mov ax,6622H | 6622 | 0000 | 2000 | 0003 | 1000 | jmp 0ff0:0100H | 6622 | 0000 | 1000 | 0000 | 1000 | mov ax,2000H | 2000 | 0000 | 1000 | 0003 | 1000 | mov ds,ax | 2000 | 0000 | 1000 | 0005 | 2000 | mov ax,[0008] | C189 | 0000 | 1000 | 0008 | 2000 | mov ax,[0002] | EA66 | 0000 | 1000 | 000B | 2000 |
注意,上述黑体部分是将内存单元中的值送入寄存器内,中括号内指明了内存单元的偏移地址,段地址由 DS 寄存器的内容决定。不同的 CS:IP 组合可能指向同一内存地址,如上述表格第二行将 CS=0FF0、IP=0100 写作 CS=1000、IP=0000,它们都执行内存单元 10000。
总结:寄存器 CS 和 IP 控制 CPU 执行指令的顺序,寄存器 DS 配合偏移地址指明数据存放的位置。
2. 检测点 3.2
(1)补全程序,使其可以将 10000H~1000FH 中的 8 个字逆序拷贝到 20000H~2000FH 中。
- 栈是一种具有后进先出(LIFO)性质的数据结构。
- 8086CPU 中入栈(push)和出栈(pop)操作都以字(两个字节)为单位,使用 SS:SP (和 CS:IP 指示指令位置类似)来指示栈顶的位置。栈顶从高地址往低地址方向增长,即入栈时 SP 的值减小、出栈时 SP 的值增大。
- 在栈为空时,SS:SP 指向栈空间最高地址单元的下一单元。
- 栈顶超界可能导致其他内存单元数据被更改而产生意向不到的情况,8086CPU 不提供限制栈顶超界的情况。
- push 和 pop 指令后可接寄存器或以中括号表示的内存单元(结合 DS 寄存器)的值。
mov ax,1000H mov ds,ax mov ax,2000H mov ss,ax mov sp,0010H push [0] push [2] push [4] push [6] push [8] push [A] push [C] push [E]
- 最后几条指令往栈内压入数据,根据题意是将数据压入内存 20000H~2000FH 内。前面已经设定好 DS 寄存器的值为 1000,所以 push [0] 操作的数据是 1000:0,后面类似。
- 所以,前面需先设定 SS:SP 的值,由于栈顶从高地址往低地址增长,所以初始时 SS=2000、SP=0010 表示栈空状态。由于 8086CPU 不支持将数据直接送放入段寄存器,而需要通过另一个寄存器周转,所以三条指令完成 SS 和 SP 指令的复制。
(2)补全程序,使其可以将 10000H~1000FH 中的 8 个字逆序拷贝到 20000H~2000FH 中。
mov ax,2000H mov ds,ax mov ax,1000H mov ss,ax mov sp,0000H pop [E] pop [C] pop [A] pop [8] pop [6] pop [4] pop [2] pop [0]
- 这题要求和上一题一样,上一题使用的是 push 指令,这道题使用 pop 指令,如 pop [E] 将栈顶元素送入内存单元 [E] 内并移动栈顶指针。内存单元的偏移地址为 000E,段地址由寄存器 DS 决定。
- 题目前两条指令已经设定好 DS 寄存器的值,和上一题类似,中间三条指令的功能是设定好 SS:SP 的值,所以初始时 CS=1000、SP=0000 表示栈满状态使得出栈元素依次放入 2000FH~20000H 中。
|