汇编语言(3)寄存器与内存访问

来源:互联网 发布:windows aero桌面性能 编辑:程序博客网 时间:2024/06/05 08:49

1、内存中字的存储

CPU中的寄存器是16位的,可以直接存储一个字,高8位存储高字节、低8位存储低字节。而这个字在内存中的存储则是另一种情况,因为内存单元只能存放一个字节,所以需要连续两个存储单元存放一个字,低字节存放到低地址单元、高字节存储到高字节单元。

2DS[address]

CPU要访问一个内存单元,则必须要先给出这个内存单元的地址,8086PC中,内存地址由段地址和偏移地址组成,DS段寄存器通常用来存放要访问数据的段地址,比如要访问1000H单元的内容:

mov bx1000H

mov dsbx

mov al[0]

上面的指令将10000中的数据读到al中。

上面的指令用到了mov指令的三种用法:1、将数据传送到寄存器;2、将寄存器中内容传递到寄存器;3、将内存单元中的数据传递到寄存器。

[…]表示一个内存单元,表示内存单元的偏移地址,而段地址直接取ds寄存器中的内容,但是上面的指令也说明了另外一个问题:不能将立即数直接传送到段寄存器!而是先将其存入一个通用寄存器,再将通用寄存器中的内容传送到段寄存器中。

8086CPU16位结构,16位指的是16根数据线!可以mov传送一个字的数据。

mov bx1000H

mov dsbx

mov ax[0]

mov [0]ax

3movaddsub指令

 

mov 寄存器,数据

mov 寄存器,寄存器

mov 寄存器,内存单元

mov 内存单元,寄存器

mov 段寄存器,内存单元

mov 内存单元,段寄存器

mov 段寄存器,寄存器

mov 寄存器,段寄存器

addsubmov的操作几乎一样

 

数据段

对于8086CPU16位),可以将一组内存单元定义为一个段,长度N<64KB,地址连续,起始地址为16的倍数的内存单元用做专门存放数据的段,从而定义了数据段,比如123B0H123B9H这段内存空间来存放数据,则知道改数据段的短地址是123BH,长度为10字节。

数据段是编程时的一种安排,将段地址写入DS中后,即可对数据段中的数据进行操作。

mov ax123BH

mov dsax

mov ax0

add al,[0]

add al,[1]

add al,[2]

将数据段的前三个内存单元数据叠加。

内存中的情况如图所示,个寄存器的初始值:CS=2000H,IP=0,DS=1000H,A=0,BX=0

1、 写入CPU执行的指令序列(汇编指令)

2、 写出每条指令执行后的CSIP和相关寄存器中的值

3、 数据和程序有区别吗?如何确定内存中哪些是数据,哪些是指令?

 

CPU提供指令以栈的形式访问内存,将一段内存空间当作栈来使用,也是编程时的一种安排,CPU提供基本的栈操作指令,入栈PUSH和出栈POP

push axax中的数据送入栈中

pop ax将栈顶数据送入ax

8086的栈操作基本单位是字。

1、 CPU如何知道一段内存空间是当作栈来使用的呢?

2、 CPU如何确定栈顶内存单元的呢?

就像CSIP中存放着当前指令的段地址和偏移地址,来确定当前要执行指令的位置。CPU要确定栈顶地址,需要另投外另个寄存器:SSSP任意时刻,SS:SP指向栈顶,SS存放栈顶内存单元的段地址,SP存放栈顶内存单元的偏移地址。

push ax的执行过程:SP=SP–2,栈顶向上移一个字的内存空间;将ax中的内容送入到SS:SP指向的内存单元。

pop ax的执行过程:将站定内存单元的数据送入axSP=SP+2注意:出栈后内存单元里的数据依然存在,只是不在栈中了,如果再次执行push,数据将被新的数据覆盖。

思考:1000FH这段内存空间当作栈来使用,初始状态的栈是空的,那么SS=1000H,SP=?

答案:0010H

栈顶越界问题:栈是内存空间中的一段,所以在栈空时执行pop,栈满时执行push使得栈顶超出这个内存空间范围,是为栈顶越界。栈顶越界是危险的,因为内存空间已经分配好,栈以外的内存空间有可能存放了用以他途的数据或指令,所以我们希望CPU帮忙解决栈顶越界的问题,但是显然CPU拒绝帮忙!它是一个绝对理性的boy,只执行当前指令,只知道当前的栈顶对应的内存单元地址。

注意:pushpop的对象可以是寄存器、内存单元(字单元)、段寄存器。

思考:10000H1000FH这段内存空间当作栈,初始状态是空的,将axbxds中的数据压栈。

mov ax1000H

mov ssax

mov sp0010H

push ax

push bx

push ds

思考:10000H1000FH这段内存空间当作栈,初始状态是空的;设置ax=001AHbx=001BH;将axbx中的数据压栈;然后将axbx清零;从栈中恢复axbx的内容

mov ax1000H

mov ssax

mov sp0010H

mov ax,001AH

mov bx,001BH

push ax

push bx

sub ax,ax; //movax,0也可以,但是需要占用3字节,sub ax,ax2字节

sub bx,bx;

pop bx

pop ax

栈段

栈段和数据段一样,长度N<=64KB,地址连续,起始地址为16的倍数的内存单元。

思考:10000H1FFFFH为栈段,初始状态为空,sp=

将一段64KB的内存空间用做栈段,栈段最底部的字单元地址为1000FFFE,所以初始栈空的状态下,SP= FFFEH+2= 0, SS= 1000H

思考:168086CPU的可设置栈段的最大空间?

答:64KB,压栈或出栈的空间超过64KBSP寄存器代表的栈顶将循环覆盖!

原创粉丝点击