8086 汇编#3

第三章 寄存器(内存访问) – 汇编语言提纲

第三章 寄存器(内存访问)

第三章 寄存器(内存访问)

3.1内存中字的存储

1.字的低位字节放在低地址单元,高位放在高地址单元

如图0、1两个内存单元存放的数据是4E20H.

这两个单元为一个起始地址为0的字单元(0地址字单元)。0为低地址单元,1为高地址单元。

1地址字单元存放的数据是124EH,1号单元存放的数据为4EH

2.任何两个地址连续的内存单元,N号单元和N+1号单元,可以看作是起始地址为N的字单元。

3.2 DS和[address]、3.3字的传送、3.5数据段

1.DS(数据段寄存器)用来存放数据所在段的段地址

2.读取10000H单元处的内容:

mov bx,1000H
mov ds,bx
mov al,[0]

其中[…]表示一个内存单元,[…]中的数字表示内存单元的偏移地址。在该用法中,8086CPU默认使用ds中的数据作为段地址。

3.不能将数据直接送入段寄存器,只能将寄存器中的数据送入段寄存器

3.4 mov add sub指令

1.mov指令

mov 寄存器,数据     ;这里的数据也叫立即数
mov 寄存器,寄存器   ;两个寄存器位数一致
mov 寄存器,内存单元
mov 内存单元,寄存器
mov 段寄存器,寄存器
mov 寄存器,段寄存器
mov 内存单元,段寄存器
mov 段寄存器,内存单元

2.add和sub指令

add 寄存器,数据
add 寄存器,寄存器
add 寄存器,内存单元
add 内存单元,寄存器
sub 寄存器,数据
sub 寄存器,寄存器
sub 寄存器,内存单元
sub 内存单元,寄存器

3.非法指令

(1)将立即数送入段寄存器

(2)add和sub指令对段寄存器进行操作

(3)add 内存单元,内存单元

4.以上的指令有两个操作对象,jmp指令具有一个操作对象。

检测点3.1

(1) 在DEBUG中,用 “D 0:0 lf” 查看内存,结果如下:

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=0,BX=0,写出每条汇编指令执行完后相关寄存器中的值

mov ax,1 
mov ds,ax 
mov ax,[0000]  ax= 2662H  
mov bx,[0001]  bx= E626H  
mov ax,bx      ax= E626H  
mov ax,[0000]  ax= 2662H  
mov bx,[0002]  bx= D6E6H  
add ax,bx      ax= FD48H  
add ax,[0004]  ax= 2C14H  
mov ax,0       ax=   0    
mov al,[0002]  ax= 00e6H  
mov bx,0       bx=   0    
mov bl,[000c]  bx= 0026H  
add al,bl      ax= 000CH  

(2) 内存中的情况如图3.6所示

各寄存器的初始值:cs=2000h,ip=0,ds=1000h,ax=0,bx=0;

①写出CPU执行的指令序列(用汇编指令写出)。

②写出CPU执行每条指令后,CS、IP和相关寄存器的数值。

③再次体会:数据和程序有区别吗?如何确定内存中的信息哪些是数据,哪些是程序?

指令序列

CS

IP

DS

AX

BX

初始值

2000h

0

0

0

0

1

mov ax,6622h

2000h

3h

0

6622h

0

2

jmp 0ff0:0100

ff0h

100h

0

6622h

0

3

mov ax,2000h

ff0h

103h

0

2000h

0

4

mov ds,ax

ff0h

105h

2000h

2000h

0

5

mov ax,[8]

ff0h

108h

2000h

c389h

0

6

mov ax,[2]

ff0h

10bh

2000h

ea66h

0

3.6~3.10 栈机制

1.栈:先进入栈的数据后出栈,后进入栈的数据先出栈。

2.栈的基本操作:入栈和出栈

3.栈的操作规则:LIFO(Last In First Out,后进先出)

4.CPU的栈机制

(1)PUSH(入栈)指令:push ax将寄存器ax中的数据送入栈中
(2)POP(出栈)指令:pop ax将栈顶数据送入ax

(3)8086的入栈和出栈都是以字为单位进行的

(4)8086中栈段寄存器为SS,栈顶指针寄存器为SP,栈顶的段地址在SS中,偏移地址在SP中。任意时刻SS:SP指向栈顶元素。

(5) push ax的执行流程

① SP=SP-2,SS:SP指向当前栈顶前面的单元,以当前栈顶前面的单元为新栈顶

② 将ax中的内容送入SS:SP指向的内存单元处,SS:SP指向新栈顶

入栈时,栈顶从高地址向低地址方向增长。

(6) 当栈为空时,SS:SP指向栈顶元素。由于栈中没有元素,SS:SP指向栈最底部单元下面的单元。该单元偏移地址为栈最底部的字单元偏移地址+2

(7) pop ax的执行过程

①将SS:SP指向的内存单元处的数据送入ax中

②SP=SP+2,SS:SP指向当前栈顶下面的单元,以当前栈顶下面的单元为新的栈顶。

注意:出栈后数据仍然在内存中,但已经不在栈中。当再次执行push等入栈指令后会在里面写入新的数据,覆盖之前的数据。

5.push、pop指令的用法

push 寄存器;将一个寄存器的数据入栈
pop 寄存器;出栈,用一个寄存器接受数据
push 段寄存器
pop 段寄存器
push 内存单元
pop 内存单元

push、pop的实质就是内存传送指令

检测点3.2

(1)补全下面的程序,使其可以将10000H-1000FH中的8个字,逆序拷贝到20000H-2000FH中。

mov ax,1000H  
mov ds,ax  
mov ax,2000H  
mov ss,ax     
mov sp,10h    
push [0]  
push [2]  
push [4]  
push [6]  
push [8]  
push [A]  
push [C]  
push [E]  

(2)补全下面的程序,使其可以将10000H-1000FH中的8个字,逆序拷贝到20000H-2000FH中。

mov ax,2000H  
mov ds,ax  
mov ax,1000H 
mov ss,ax    
mov sp,0     
pop [e]  
pop [c]  
pop [a]  
pop [8]  
pop [6]  
pop [4]  
pop [2]  
pop [0]  

实验2 用机器指令和汇编指令编程

1.debug的使用(二)

(1)D 段寄存器:偏移地址查看内存中的数据

(2)E\A\U也可以用段寄存器表示内存单元段地址

(3)DEBUG在用T命令执行修改寄存器SS的指令时,下一条指令也紧接着被执行

2.实验任务

(1)使用DEBUG,将上面的程序段写入内存,逐条执行,根据指令执行后的实际运行情况填空。

mov ax,ffff
mov ds,ax
mov ax,2200
mov ss,ax
mov sp,0100

mov ax,[0];ax= 5BEAH 
add ax,[2];ax= 5CCAH 
mov bx,[4];bx= 31F0H 
add bx,[6];bx= 6122H 

push ax;sp= 00FEH ,修改的内存单元地址是 2200:00FE 内容为 5CCAH 
push bx;sp= 00FCH ,修改的内存单元地址是 2200:00FC 内容为 6122H 
pop ax;sp= 00FCH ,ax= 6122H 
pop bx;sp= 00FEH ,bx= 5CCAH 

push [4];sp= 00FEH ,修改的内存单元地址是 2200:00FE 内容为 31F0 
push [6];sp= 00FCH ,修改的内存单元地址是 2200:00FC 内容为 2F32 
此实验答案不定,需根据每台机器的实际运行情况。

(2)仔细观察图3.19中的实验过程,然后分析:为什么2000:0~2000:F中的内容会发生改变?

答:因为在debug使用T等指令引发了中断造成的,中断过程使用当前栈空间存放cpu关键数据,所以,你的栈里就有些不是你操作的数据了。

因为如果是在中断过程中压栈是栈越界的话,在windows下的命令窗口会强制关闭的。这个可能在你跟踪一些程序的时候会遇到。

发表评论

滚动至顶部