抄书笔记-汇编语言 第三章 寄存器(内存访问)

3.1内存中的字存储

在CPU中,我们使用16位的寄存器来存储一个字。高八位存放高字节,低八位存放低字节。由于内存单元是一个字节单元(就是说一个单元存放一个字节),所以一个字需要两个地址连续的内存单元来存放,这个字的低位存放在低地址单元中,高位存放在高地址中。

字单元:即存放一个字型数据(16位)的内存单元,由两个地址连续的内存单元组成。任何两个地址连续的内存单元,N号单元和N+1号单元,可以将它们看作两个内存单元,也可以看做是一个地址为N的字单元中的高位字单元和低位字单元。

3.2DS和[address]

cpu要读写一个内存单元的时候,必须要给出这个内存单元的地址,在8086PC中,内存地址由段地址和偏移地址组成。在8086的CPU中有一个DS段寄存器,通常用来存放要访问的数据的段地址。

比如:

mov bx,1000h;
mov ds,bx
mov al,[0]

上面这条指令用于将10000H(1000:0)处的数据读取到al;

使用mov指令我们可以完成两种传递:

  1. 将数据直接送入寄存器
  2. 将一个寄存器中的内容送入到另外一个寄存器

在8086cpu中,自动获取ds中的数据作为内存单元的段地址。在8086的cpu中,我们不支持直接将数据送入到段寄存器,我们只能先将数据送入到通过寄存器,在将通用寄存器中的数据mov到段寄存器。

3.3字的传送

只需要在操作的时候,指定操作的寄存器是字节单元,还是字单元就可以了。比如:

mov ax,1000H
mov ds,ax
mov ah,[0]

只是把内存地址是10000H的一个字节传动到ah里面。

但是

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

则会将内存地址10000H的数据存放在bx里面,其中bh存放的是高位,就是10001H的数据,bl存放的是低位,10000H的数据。

3.4mov,add,sub

到现在,我们已经知道mov指令的几种组合:

操作 实例
mov 寄存器,数据 比如:mov ax,8
mov 寄存器,寄存器 比如:mov ax,bx
mov 寄存器,内存单元 比如:mov ax,[0]
mov 内存单元,寄存器 比如:mov [0],ax
mov 段寄存器,寄存器 比如:mov ds,ax
mov 寄存器,段寄存器 比如:mov ax,ds
mov 内存单元,段寄存器 比如:mov [0],cs
mov 段寄存器,内存单元 比如:mov ds,[0]

3.5数据段

在汇编,把一段内存作为数据段是一种编程时候的人为安排,可以在具体操作的时候,用ds存放数据段的段地址,在根据实际的需要来访问数据的具体单元。

比如:将123B0~123B9的内存定义为数据段,现在要累加数据段中前三个单元的数据。

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

如果是累加前面的三个字型单元的话:

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

3.1-3.5小结

1.字在内存中存储的时候,需要使用两个连续的内存单元来存储,字的低放在低地址空间里面,高位存放在高地址单元中。
2.可以使用mov指令来访问内存单元,可以在mov指令中只指定给出单元的偏移地址,此时,默认的段地址保存在DS段寄存器中。
3.[address]表示偏移地址是address的内存单元。
4.在内存和寄存器之间传递字型数据时,高地址单元和高8位寄存器,低地址单元和低8位寄存器相对应。
5.mov,add,sub是具有两个操作对象的指令。jmp是具有一个操作对象的指令。
6.可以根据自己的推测,在debug中实验指令对象。

3.6栈

栈是一个特殊的数据处理形式,具有后进先出的操作方式。

一个开口的盒子就可以看做是一个栈空间,每一次将一个本书放到盒子的底部,拿出书的时候也是拿出最后放进去的那一本书。

从盒子的原型,我们可以看到栈有两个比较基本的操作:入栈和出栈

入栈是将一个新的元素放到栈顶,出栈是从栈顶取出一个元素。栈顶的元素总是最后入栈,需要出栈时,又最先被从栈中取出。称为LIFO(Last In First Out,后进先出)。

3.7CPU提供点栈机制

8086CPU提供了入栈和出栈指令, 最基本的两个是PUSH(入栈)和POP(出栈)。

比如:push ax是将寄存器ax中的数据送入栈中,pop ax表示从栈顶取出数据送入ax。

8086CPU的入栈和出栈都是以字为单位进行的

在8086CPU中,有两个寄存器,段寄存器SS和寄存器SP,栈顶的段地址存放在SS中,偏移地址存放在SP中。任意时刻,SS:SP指向栈顶元素。push指令和pop指令执行时,CPU从SS和SP中取得栈顶地址。

push ax的执行步骤:

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

2. 将ax中的内容送入SS:SP指向内存单元中,SS:SP此时指向新栈顶。

3.8栈顶超界的问题

在执行push,pop时候,容易发生栈顶超界问题,当栈满的时候再使用push指令入栈,或者是栈空的时候使用pop指令出栈,都将发生栈顶越界的问题。

在8086的cpu中,它是不会自动给我们检查栈顶越界的问题的,要根据可能用到的最大栈空间,来安排栈的大小,防止入栈时候数据太多而导致的超界;执行出栈时候也要注意,以防止栈空的时候出栈而导致的越界。

3.9push,pop指令

push和pop指令是可以在寄存器和内存之间传送数据。

指令格式如下:

push 寄存器

pop 寄存器

也可以是段寄存器

push 段寄存器

pop 段寄存器

也可以是内存地址

只需要指定偏移地址,段地址也是从ds里面获取

push 内存单元

pop 内存单元 ;注意 都是字操作

代码:

mov ax,1000H
mov ds,ax
push [0]
pop [2]

代码需求,将10000H-1000FH这段空间当做栈,初始状态为空,将ax,bx,ds中的数据入账:

mov ax,1000H
mov ss,ax  ;不能直接操作段寄存器,需要先弄到寄存器中
mov sp,0010H
push ax
push bx
push ds

代码需求

1.将10000H-1000FH这这段空间作为栈,初始状态时空的

2.设置AX=001AH,BX=001BH

3.将AX,BX中的数据入栈

4.然后清空AX,BX

5.从栈中恢复AX,BX原来的内容

mov ax,1000H
mov ss,ax
mov sp,0010H
mov ax,001AH
mov bx,001BH
push ax
push bx

sub ax,ax
sub bx,bx 字节码是2 mov bx,0 字节码是3
pop bx
pop ax ;后进先出

代码需求

1.将10000H-1000FH这段空间作为栈,初始状态是空的

2.设置ax=001AH,bx=001BH

3.利用栈,实现ax和bx的数据交换

mov ax,1000H
mov ss,ax
mov sp,0010H

mov ax,001AH
mob bx,001BH

push ax
push bx

pop ax
pop bx

栈的综述

1.在ss:sp中存放的是栈顶的段地址和段偏移地址,提供了入栈指令push和出栈指令pop
2.push指令的操作步骤a:sp=sp-2;b:向ss:sp指向的字单元中送入数据
3.pop指令的操作步骤:a:从ss:sp指向的字单元中读取数据;b:sp=sp+2;
4.任意时刻,ss:sp指向栈顶元素
5.8086CPU只记录栈顶,栈空间的大小我们要自己管理
6.用栈来暂存以后需要恢复的寄存器内容时,寄存器出栈的顺序要和入栈的顺序相反
7.push,pop实质上是一种内容传送指令
  栈一种比较重要的机制,一定要深入理解,灵活掌握。

3.10栈段

一段被当作是栈来使用的内存空间,我们称之为栈段。

把一段内存地址当作是栈段,是我们在编程时候的安排,CPU并不会由于这种安排,就在执行pop和push的时候,自动把这段内存地址当作是栈来使用,而是将SS:SP指向的定义的栈段。

8086CPU中一个栈最大可以设置为64K,范围是0000~FFFFH.

段的总和描述:

我们可以将一个内存定义为一个段,用一个段地址来指示段,一个偏移地址来指示访问的段内单元,这完全是我们的安排.

我们可以使用一个段来存放数据,将它定义为数据段。
我们可以使用一个段来存放代码,将它定义为代码段。
我们可以使用一个段来当作栈,将它定义为栈段。

对于数据段,将它的段地址放在DS中,使用mov,sub,add等访问内存的时候,CPU就将我们定义的数据段中的内容当作数据来访问。
对于代码段,将它的段地址放在CS中,将段中的第一条指令的偏移地址放在IP中,这样CPU就将执行我们定义的代码段中的指令。
对应栈段,将它的段地址放在SS中,将栈顶单元的偏移地址放在SP中,这样CPU在执行指令push,pop的时候,就当作是一个栈段地址空间来使用了。

实例代码:

mov ax,1000H
mov ss,ax
mov sp,0020H
mov ax,cs
mov ds,ax
mov ax,[0]
add ax,[2]
mov bx,[4]
add bx,[6]
push ax
push bx
pop ax
pop bx

一段内存,既可以是代码段的存储空间,也可以是数据的存储空间,也可以是栈空间,也可以什么都不是,关键是看CPU中寄存器的设置:即cs,ip,ss,sp,ds的指向。

共有 0 条评论

Top