汇编2 访问寄存器和内存

目录

第2章 访问寄存器和内存

2.1、CS、IP和代码段

1、CS和IP寄存器

2、演示

2.2、Jmp指令

1.应用背景

2、问题分析

3、debug演示

 2.3、内存中字的存储

1、存储规则

2、字单元

 2.4、用DS和[address]实现字的传送

1、原理

2、字的传送

2.5、 DS和数据段

1、对内存单元中数据的访问

2、用mov指令操作数据

3、加法add和减法sub

4、小结

2.6、 栈及栈操作的实现

1、栈结构

2、指令

3、相关的寄存器

4、小结

2.7、关于段的总结

1、各种段

2、综合示例


 

第2章 访问寄存器和内存

2.1、CS、IP和代码段

1、CS和IP寄存器

CS:代码段寄存器
IP:指针指令寄存器
CPU将CS:IP指向的内存单元中的内容当作指令执行

 8086CPU工作原理

1.从CS :IP指向的内存单元读取指令,将读取的指令送入指令缓存器。
2.IP=IP+所读指令的长度,从而指向下一条指令。
3.转到步骤1,执行全过程。

2、演示

在2000:0000处执行下列代码

mov ax,0123H
mov bx,0003H
mov ax,bx
add ax,bx

e67ad756093eda8945b701647f0ff285.png421d3521cf51df5423047adb4215579e.png141923c99159d3fe80c09a4dad3609e7.png

 

2.2、Jmp指令

1.应用背景

指向何处的指令,取决于CS:IP,可以通过改变CS:IP的内容,来控制CPU要执行的目标命令。

问题:如何修改CS、IP的值?

1.Debug中使用R命令修改
Debug是调试手段,非程序方式。

2.用指令修改(非法)
8086CPU不提供对CS和IP修改的指令

3.转移指令jmp
(1)同时修改CS、IP的内容
jmp 段地址:偏移地址
(2)仅修改IP的内容
jmp 某一合法寄存器(通常为通用寄存器)
例:jmp ax(类似于mov IP,ax)
跳转到IP寄存器值为ax值处执行

 

2、问题分析

从2000:0000处开始执行,则执行序列是?

4aa6a1221b0685ada617c39db6b9d602.png

 解:

mov ax,6622H        //cs=2000,ip=0    

jmp 1000:3        //cs=1000,ip=3

mov ax,0

mov bx,ax

jmp bx        //cs=1000,ip=0

mov ax,0123H

 

3、debug演示

16a14db4391315b64e0f1aa122f7ec1b.pngac76ad4abd8d9a7b8883f4c70de0aee1.png418c905bbc9fbf6df5e0df4169c46f68.png438c15b415eb973e44e0c01d8579e1bb.png

 

 2.3、内存中字的存储

1、存储规则

对于8086CPU,16位作为1个字

16位的字存储在1个16位的存储器中,高8位放高字节(AH)、低8位放低字节(AL)

例如:20000D(4E20H)存放0、1两个单元,18D(0012H)存放在2、3两个单元。 

AHAL
4E(H)

20(H)

020H
14EH
212H
300H
4 
4 
300H
212H
14EH
0

20H

0号是低地址,1号是高地址

 

2、字单元

字单元是由2个地址连续的内存单元组成,存放1个字型数据(16位)。

原理:在1个字单元中,低地址单元存放低位字节,高地址单元存放高位字节

在起始地址为0的单元中,存放的是4E20H;

在起始地址为2的单元中,存放的是0012H。

0

20H
14EH
212H
300H
4 

 问题:

(1)0地址单元中存放的字节型数据是(20H)

(2)0地址字单元中存放的字型数据是(4E20H)

(3)2地址单元中存放的字节型数据是(12H)

(4)2地址字单元中存放的字型数据是(0012H)

 

 2.4、用DS和[address]实现字的传送

1、原理

CPU从内存单元中读取数据时,必须给出这个内存单元的地址。

内存地址由段地址和偏移地址组成(段地址:偏移地址)

使用DS寄存器和[address]配合

1.用DS寄存器存放要访问的数据的段地址
2.偏移地址用[...]形式直接给出

使用通用寄存器将段地址送入DS寄存器

8086CPU不支持将数据直接送入寄存器(硬件设计的问题),故必须通过通用寄存器才能将数据送入段寄存器。

mov bx,1000H
mov ds,bx

例如:将10000H(1000:0)中的数据读到al中

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

 

2、字的传送

8086CPU可以一次性传送1个字(16位)数据。

例1:已知内存和指令如下

10000H23

10001H

11
10002H22
10003H66
mov ax,1000H
mov ds,ax
mov ax,[0]
mov bx,[2]
mov cx,[1]
add bx,[1]
add cx,[2]

Debug实现如下

3f78e13ee66fa7789ca74195eb244cbe.pngc4481339fc50cddaea7063e5ddddf236.pngd45deef3b97458daef90b81a74e6f1f6.png

 

例2:已知内存和指令如下

10000H23
10001H11
10002H22
10003H11
mov ax,1000H
mov ds,ax
mov ax,2C31
mov [0],ax
mov bx,[0]
sub bx,[2]
mov [2],bx

Debug执行如下

df071197ca8b933ad6fc0e1bf3b27afb.png

657fd801664724c9c9f37ecdbf708dae.png9229d8c2baefa91ccf3ef0297525cdff.png

08a266d7ef83e39e5e3c22ebfde0f3c5.png

 

2.5、 DS和数据段

1、对内存单元中数据的访问

对于8086CPU,可以根据需要将一组内存单元定义为一个段。

        物理地址=段地址X16+偏移地址

        将一组长度为N(N<64K)、地址连续、起始地址为16的倍数的内存单元当作专门存储数据的内存空间,从而定义了一个数据段。

DS:[address]

用DS存放数据段的段地址
用相关指令访问数据段中的具体单元,单元地址由[address]指出

已知将123B0H~123BAH的内存单元定义为数据段

例1:累加数据段中的前3个单元中的数据

mov ax,123BH
mov ds,ax
mov al,0
add al,[0]
add al,[1]
add al,[2]

b346408dabe99d462fb32a1ffe2193a5.png53cd773fda6e2e99e4794c142df955cc.pngc2bf1f956aa2993bfb571db4a86839ea.png

 

例2:累加数据段中的前3个字型数据

mov ax,123BH
mov ds,ax
mov ax,0
add ax,[0]
add ax,[2]
add ax,[4]

1921074ffe36859504d89af2c4cf4ab6.pngf865f261e393f424bd2804dfd915c706.png3881131bca85b4c3a13f896a47ab53c7.png

 

2、用mov指令操作数据

d246f08210957343beed6f23f0b6669c.png

已知:mov 段寄存器,寄存器。推测1—>mov 寄存器,段寄存器

已知:mov 内存单元,寄存器。推测2—>mov 内存单元,段寄存器;推测3—>mov 段寄存器,内存单元

已知:mov 段寄存器,数据。推测4—>mov 段寄存器,数据

 

3、加法add和减法sub

f957825ac28509458f87253a754b604f.png78d9f020311d4a35677edf98a8193c81.png

4、小结

97859d769ee182ef13ca69832fffd7f2.png

 

2.6、 栈及栈操作的实现

1、栈结构

栈结构是一种能能够在一端进行插入或删除的数据结构

两个基本操作:入栈和出战

入栈:将一个新元素放到栈顶;
出栈:从栈顶取出一个元素

 操作规则:后进先出

 

2、指令

push(入栈)和pop(出栈)

push ax:将ax中的数据送入栈中

pop ax:从栈顶取出数据送入ax中

(以字为单位对栈进行操作)

 例如:设将10000H~1000FH内存当作栈来使用

mov ax,1000H
mov ss,ax
mov sp,0010H    //栈顶地址为1000:0010

mov ax,0123H
push ax
mov bx,2266H
push bx
mov cx,1122H
pop ax
pop bx
pop cx
10000H 
... 
10009H 
1000AH22
1000BH11
1000CH66
1000DH22
1000EH23
1000FH01

结果ax=1122H;bx=2266H;cx=0123H

 

3、相关的寄存器

栈段寄存器SS——存放栈顶的段地址

栈顶指针寄存器SP——存放栈顶的偏移地址

任意时刻,SS:SP指向栈顶元素。

push ax
    (1)sp=sp-2
    (2)将ax中的内容送入SS:SP指向的内存单元处,
    SS:SP此时指向新栈顶

pop ax
    (1)将SS:SP指向的内存单元处的数据送入ax中
    (2)sp=sp+2,SS:SP指向当前栈顶下面的单元,
    以当前栈顶下面的单元为新的栈顶

栈顶超界问题
8086CPU不保证对栈的操作不会越界

 

4、小结

 (1)push、pop实质上是一种内存传送指令,可以在寄存器和内存之间传送数据,于mov指令不同的是,push和pop指令访问的内存单元的地址不是在指令中给出的,而是由SS:SP指出的。

(2)执行push和pop指令时,SP中的内容自动改变

(3)8086CPU提供的栈操作机制
 

push指令执行步骤

        1)SP=SP-2

        2)向SS:SP指向的字单元中送入数据

pop指令执行步骤

        1)从SS:SP指向的字单元中读取数据

        2)SP=SP+2

 

 

2.7、关于段的总结

1、各种段

物理地址=段地址X16+偏移地址

段地址指使段,用偏移地址访问段内的单元

数据段

将段地址放在DS中
CPU将定义的数据段中的内容当作数据段访问

代码段

 将段地址放在CS中,将段中第一条指令的
偏移地址放在IP中。
 CPU执行定义的代码段的指令

栈段

 将段地址放在SS中,将栈顶元素
的偏移地址放在SP中。
 CPU执行栈操作(push、pop)时,
将定义的栈段当作地址空间使用。

 

2、综合示例

按要求设置段并执行程序

设10000H~1000FH为数据段,10010H~1001FH为栈段,20000H~2FFFF为代码段。

(10000H)=23、(10001H)=11、(10002H)=22、(10003H)=66
 

mov bx,1000H

mov ds,bx

mov ss,bx

mov sp,10H

mov ax,[0]

mov bx,[2]

push ax

push bx

pop ax

pop bx

mov [0],ax

mov [2],bx

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值