您的位置:首页 > 其它

王爽 《汇编语言》 读书笔记 三 寄存器(内存访问)

2017-08-20 19:14 344 查看
第三章  寄存器(内存访问)

3.1 内存中字的存储

cpu中, 用16位寄存器来存储一个字。高8位存放高位字节,低8位存放低位字节。

字单元:即存放一个字型数据(16位)的内存单元,由两个地址连续的内存单元组成。高地址内存单元中存放字型数据的高位字节,低地址内存单元中存放字型数据的低位字节。

将起始地址为N的字单元简称为N地址字单元。

3.2 DS和[address]

DS用来存放要访问数据的段地址。例如要访问10000H单元中的内容

mov bx, 1000H
mov ds, bx
mov al, [0]
以上指令将1000H(1000:0)的数据读到al中。

mov指令 将数据送入寄存器   将一个寄存器中的内容送入令一个寄存器

也可以将一个内存单元中的内容送入一个寄存器中。

[] 表示内存单元。 方括号中的内容表示内存单元的偏移地址。

8086cpu 自动取ds中的数据为内存单元的段地址。

8086不支持直接把数据送入段寄存器的操作  move ds,1000H 这条语句是非法的。

先将数据送入通用寄存器,然后再mov ds, bx  这是8086cpu的硬件设计

以下代码将寄存器al中的数据送至内存地址10000H中

mov bx, 1000H
mov ds, bx
mov [0], al
mov [内存单元地址], 寄存器名

3.3 字的传送

mov bx, 1000H
mov ds, bx
mov ax, [0]    ; 此处传入字型数据送入ax
mov [0], cx    ;传出字型数据送到1000:0处


3.4 mov, add, sub

mov 寄存器,数据

mov 寄存器,寄存器

mov 寄存器,内存单元

mov 内存单元,寄存器

mov 段寄存器,寄存器

推测

1)根据推测mov 段寄存器,寄存器   -》mov 寄存器,段寄存器

2)mov 内存单元,寄存器    =》 mov 内存单元,段寄存器
3)mov段寄存器,内存单元 (但是不支持mov 段寄存器,数据)

不可以使用内存单元给CS赋值

提示错误如下



也不可以直接使用内存单元给内存单元赋值

add命令和sub指令同mov一样有以下几种形式

add 寄存器,数据

add 寄存器,寄存器

add 寄存器,内存单元

add 内存单元,寄存器

sub 寄存器,数据

sub 寄存器,寄存器

sub 寄存器,内存单元

sub 内存单元,寄存器

sub和add无法直接操作段寄存器



3.5 数据段

中8086中可以将长度为N 地址连续起始是16倍数段内存单元当作专门存储数据段空间,从而定义了一个数据段。  比如 123B0H~123B9H 段地址为123B 长度10个字节

比如将123B0H~123B9H的内存单元定义为一个数据段。现在要累加这个数据段中前3个单元的数据,代码如下

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


3.1~3.5 小结
1)字中内存中存储时,要用两个地址连续的内存单元来存放,字的低位字节存放中低地址单元中,高位字节存放中高地址单元中。

2)用mov指令访问内存单元,可以中mov指令中只给出单元的偏移地址,此时,段地址默认存放中DS寄存器中

3)【address】表示一个偏移地址为address 的内存单元

4)中内存和寄存器之间传送字型数据,高位地址单元和高8位寄存器,低位地址单元和低8位寄存器相对应。

5)mov,add,sub是具有两个操作对象段指令。jmp是具有一个操作对象的指令。

3.6 栈

一种具有特殊访问方式的存储空间(也称为数据结构)

后入先出。

栈有两个操作,入栈和出栈。入栈就是将元素放栈栈顶,出栈就是从栈顶取出一个元素。

3.7 cpu提供的栈机制

PUSH 入栈  POP 出栈 

8086的出栈和入栈以字为单位

栈中字型数据以2个单元存放,高地址存放高8位,低地址存放低8位。栈底采用高地址,栈顶低地址。

SS 栈段寄存器

SP 栈偏移地址寄存器 

SS:SP指向栈顶元素

push ax 有以下两步组成

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

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

栈空SP指向栈空间最高地址单元的下一个单元

pop ax 执行过程和push ax 完全相反

1)将SS:SP指向的内存单元处的数据送入ax中(低位-》低位,高位-》高位)

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

3.8 栈顶超界问题

当栈满的时候再使用push指令入栈,或栈空的时候再使用pop指令出栈,都将发生栈顶超界问题。

8086CPU不保证我们对栈对操作不会超界。 8086只考虑当前前对情况:当前对栈顶在何处,当前要执行对指令是哪一条。

编程的时候要自己小心栈顶超界的问题,要根据可能用到的最大空间来安排栈的大小,防止入栈的数据太多导致超界;执行出栈的时候也要注意,防止栈空的时候继续出栈而导致超界。

3.9 push, pop指令

push 寄存器

pop 寄存器

push 段寄存器

pop 段寄存器

push 内存单元

pop 内存单元

问题3.7

将10000H~1000FH这段空间当作栈,初始状态是空的,将AX,BX,DS中的数据入栈。

mov ax, 1000H
mov ss, ax   ;设置栈地址
mov sp, 0010H  ;设置栈顶
push ax
push bx
push ds


问题3.8

出栈顺序要和入栈顺序相反,因为最后入栈的寄存器内容栈栈顶,所以恢复时,要先出栈。

问题3.9

将10000H~1000FH当作栈空间

设置AX = 001AH, BX=00BH

利用栈交换AX和BX的数据

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

mov ax, 001a
mov bx, 001b

push ax
push bx

pop ax
pop bx


注意:push,pop等操作指令,修改的只是SP。也就是说,栈顶变化范围最大为:0~FFFFH

提供SS,SP指示栈顶。 push操作先改变SP后写入栈指令。  pop操作先读取数据后改变SP执行出栈指令。

栈的综述

1)8086cpu提供的栈操作机制如下

在SS,SP中存放栈顶的段地址和偏移地址

提供入栈和出栈指令,它们根据SS:SP指令的地址,按照栈的方式访问内存单元。

2)push指令步骤。 SP=SP-2;  向SS:sp指向的字单元中写入数据

3)pop指令执行步骤:从SS:SP指向的字单元中读取数据; SP=SP+2

4)任意时刻SS:SP指向栈顶元素

5)8086只记录栈顶,栈空间的大小要我们自己管理

6)用栈来暂存以后需要恢复的寄存器内容,寄存器出栈顺序和入栈顺序相反。

7)push,pop实质上是一种内存传送指令

3.10 栈段

将一段内存当作栈段,仅仅是编程时的一种安排。CPU并不会由于这种安排栈执行push pop等栈操作指令时会自动将我们定义的栈段当作栈空间来访问。

段的综述

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

我们可以用一个段存放数据,将它定义为“数据段”

我们可以用一个段存放代码,将它定义为“代码段”

我们可以用一个段当作栈,将它定义为“栈段”

对于数据段,将它的段地址放在DS中,用mov add sub等反问内存单元的指令时,CPU将我们定义的数据段中的内容当作数据访问。

对于代码段,将他的段地址防止CS中,将段中第一条指令的偏移地址放在IP中。cpu就执行我们定义的代码段中的指令;

对于栈段,将它的段地址放在ss中,将栈顶单元的偏移地址放在SP中,中cpu执行push pop指令时候,就会将我们定义的栈段当作栈空间来使用。

debug命令栈执行修改栈段SS的指令时,下一条指令也紧接着被执行
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  汇编语言