汇编语言学习分享(三)

扶醉桌前 提交于 2020-01-15 21:56:37

字的存储

在上一篇中说到一个16位寄存器可以存放一个字(16位)或者一个字节(8位),当存放一个字节的时候只需要一个内存单元(内存单元是以字节为单位的,8位),而存放一个字需要两个内存单元,这样存放一个字就需要两个连续的内存单元,这个16位的字,高位存放在高地址,低位存放在低地址

内存地址 内存数据
0 20H
1 4EH
2 12H
3 00H

对于字来说0就是低地址单元,1是高地址单元,则字型数据4E20H的低地址位20存放在0号单元,高地址位4E存放在高地址单元,因为它的起始地址为0,又可以称作0地址字单元。

段地址寄存器

通过前面学过的知识我们可以知道当CPU想要对一个内存单元进行操作时,必须知道它的地址,要知道内存单元的地址就要知道它的段地址和偏移地址,在8086 CPU中,DS寄存器就是用来存放段地址的,执行指令的时候,CPU会自动读取DS中的数据为内存单元的段地址,使用[偏移地址]来表示偏移地址,假设DS寄存器中此时存放的是1000H,那么mov al,[0]就表示将10000H(物理地址=段地址x16+偏移地址)地址上存放的数据存到al中。
如果想要修改DS寄存器中的值,那么直接使用mov指令将数字存到DS寄存器中是不行的,只能先将值存到一个寄存器中,再使用mov指令将这个寄存器中的值存到DS中,例:

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

这样就将地址为10000H处的值存放到ax寄存器中了,也就是将下表中的4E20H存放到ax中。(ax是十六位,一个字,两个字节)

内存地址 内存数据
0 20H
1 4EH
2 12H
3 00H

所以一个内存单元地址的确定可以通过段地址DS+[偏移地址]进行确定

add和sub指令

顾名思义,add指令就是用来做加法操作的,sub指令就是用来做减法操作的,例如add ax,8这条指令相当于C语言中的ax = ax + 8sub ax,8相当于C语言中的ax = ax - 8
add和sub指令可以操作的对象有以下几种形式,以add指令为例:

add 寄存器,数据        例如:add ax,8
add 寄存器,寄存器      例如:add ax,bx
add 寄存器,内存单元        例如:add ax,[0]
add 内存单元,寄存器        例如:add  [0],ax

栈,是一段具有特殊访问方式的存储空间,它的存取规则是先进后出,后进先出,就像是一个上面没有盖的桶,最后放进去的东西只能最先取出来。
那么我们怎么知道在连续的存储空间中,哪一段是栈,哪一段不是栈,回想一下,CPU是根据CS、IP两个寄存器中存放的值判断当前指令存放的位置,根据DS、偏移地址判断数据存放在哪个内存单元,显然,也会有相应的寄存器用来判断哪一段是栈,在8086 CPU中,通过段寄存器SS和寄存器SP就可以确定栈的位置,栈有栈顶和栈底,栈顶的段地址存放在SS中,SP用于存放偏移地址,在任意时刻SS:SP指向栈顶元素,它指向的第一个元素可以理解为栈底,以后每存放一个数据SS:SP就向上提升,而它所指向的就是栈顶。

PUSH和POP指令

有了栈,那么就可以对栈进行存取数据的操作,使用的指令时push和pop指令,push指令用于入栈操作,也就是存数据,pop指令用于出栈,也就是取数据。8086 CPU的入栈、出栈操作都是以字为单位
假设有如下一段连续的内存单元,此时SS为1000H,SP为000EH,AX为1234H,栈顶为1000EH。

内存地址 数据
1000AH
1000BH
1000CH
1000DH
1000EH
1000FH

首先,因为SS为1000H,SP为000EH,所以栈顶是指向1000EH位置的:
SS为1000H,SP为000EH,AX为1234H

内存地址 数据
1000AH
1000BH
1000CH
1000DH
1000EH [SS:SP]
1000FH

接着我们执行入栈操作,将AX(1234H)入栈,使用push ax操作进行压栈。
SS为1000H,SP为000CH,AX为1234H

内存地址 数据
1000AH
1000BH
1000CH 34[SS:SP]
1000DH 12
1000EH
1000FH

此时,新的栈顶就变成了1000CH,接着,我们再将一个立即数5678H压入栈中,使用push 5678
SS为1000H,SP为000AH,AX为1234H。

内存地址 数据
1000AH 78[SS:SP]
1000BH 56
1000CH 34
1000DH 12
1000EH
1000FH

这是,栈顶就是1000AH,SS为1000H,SP为000AH。
演示完了入栈,我们再进行出栈,使用pop ax操作,将出栈的数据放入到ax寄存器中:
SS为1000H,SP为000CH,AX为5678H。

内存地址 数据
1000AH 78
1000BH 56
1000CH 34[SS:SP]
1000DH 12
1000EH
1000FH

注意,出栈并不意味着之前写入内存单元的数据被删除了,之前写入的数据还是存在的,只不过它不在栈中了。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!