汇编第三章
数据都不能和段地址发生直接替换,要借用寄存器
Debug的T命令在执行修改寄存器SS的指令时,下一条指令也要紧接着被执行
3.1 内存中字的存储
存放方式
在0地址处开始存放20000(4E20H)
0 | 20H
1 | 4EH
2 | 12H
3 | 00H
4 |
5 |
上低下高
(字型要考虑两个字节)
(字节型数要考虑1个字节)
0地址单元中存放的字节型数据为 20H
0地址字单元中存放的字型数据为 20000(4E20H)
2地址字单元中存放的字节型数据为12H
2地址字单元中存放的字型数据为0012H
1地址字单元中存放的字型数据为 124EH
3.2 DS和[address]
8086CPU中有一个DS寄存器,通常用来存放要访问的数据的段地址
将数据直接送入寄存器 mov ax,2
将一个寄存器中的内容送入另一个寄存器中 mov bx,ax
还可以将一个内存单元中的内容送入一个寄存器。mov a1,[0]
mov 寄存器名,内存单元地址
[…]表示一个内存单元,[…]中的0表示内存单元的偏移地址
执行指令时,8086CPU自动取DS中的数据为内存单元的段地址
不能mov ds,1000H
只能 mov bx,1000H
mov ds,bx
数据->通用寄存器->段寄存器
将al中的数据送入内存单元10000H
mov bx,1000H
mov ds,bx
mov [0],al
3.3 字的传送
8086CPU是16位结构,有16根数据线,所以,可以 一次性传送16位的数据,也就是一次性传送一个字。
一个字=两个字节
3.4 mov add sub
Sub是减法
3.5 数据段
可以根据需要将一组内存单元定义为一个段(可以是代码段、数据段等)
可以将一组长度为N(N<=64K)、地址连续、起始地址为16的倍速的内存单元当作专门存储数据的内存空间,从而定义了一个数据段
123B0H-123B9H
段地址:123BH
长度:10字节
如何访问数据段中的数据
将ds指到头
累加123B0H的前三个字节单元的数据
累加123B0H的前三个字型单元的数据
3.6 栈
栈是一种具有特殊的访问方式的存储空间。它的特殊性就在于,最后进去这个空间的数据,最先出去
入栈:将一个新的元素放到栈顶;
出栈:从栈顶取出一个元素。
操作原则:LIFO
3.7 CPU提供的栈机制
CPU都有栈的设计
push是入栈
pop是从栈顶
push ax :将寄存器ax中的数据送入栈中(从栈底开始添入)
pop ax :从栈顶取出数据送入ax(取出后将栈顶数据存在,是覆盖的)
8086CPU的入栈和出栈操作都是以字型为单位进行的
字型是两个单元
8086CPU中有两个寄存器:
段寄存器SS 存放栈顶的段地址
寄存器SP 存放栈顶的偏移地址
任何时刻,SS:SP指向栈顶元素
例子:
push ax
(1)SP=SP-2;
(2)将ax中的内容送入SS:SP指向的内存单元出,SS:SP此时指向新栈顶
将10000H-1000FH当作栈,初始状态是空
SS=1000H SP=0010H
格式化就是指向0,数据并没有删除,只是等待被覆盖,所以要多次覆盖在格式化,才能清除干净
3.8 栈顶超界的问题
栈顶超界是危险的,入栈出栈时的不小心,而将这些数据、代码意外地改写,将会引发一连串的错误。
8086CPU不保证对栈的操作不会超界。
8086CPU只知道栈顶在何处(由SS:SP),而不知道读者安排的栈空间有多大。
3.9 push、pop指令
Push 寄存器:将一个寄存器中的数据入栈
Pop 寄存器:出栈,用一个寄存器接收出栈的数据
Push ax
Pop bx
Push 段寄存器:将一个段寄存器中的数据入栈
Pop 段寄存器:出栈,用一个段寄存器接收出栈的数据
Push ds
Pop es
Push 内存单元:将一个内存单元处的字入栈
栈的操作都是以字为单位
Pop 内存单元:出栈,用一个内存字单元接收出栈的数据
Push [0]
Pop [2]
CPU段地址都是从ds中获得
Xor 异或
Xor ax,ax
一样等于0
不一样等于1
3.10 栈段
我们可以将长度为N(N<=64K)的一组地址连续、起始地址为16的倍数的内存单元,当作栈在用,从而定义了一个栈段。
10000H-1FFFFH这段空间当作栈段,初始状态栈是空,此时SS=1000H,SP=0
10000H-1FFFFH这段空间当作栈段,SS=1000H,栈空间大小为64KB,栈最底部的字单元地址为1000:FFFE
任何时刻,SS:SP指向栈顶,当栈中只有一个元素的时候,SS=1000H,SP=FFFEH
Push和pop只能修改SP,SS是不发生改变的
一个栈段的容量最大为64KB