寄存器(内存访问)
内存中字的存储
内存是连续的单元,一个单元存放一个Byte, 8位。
譬如从0~10000, 0就叫低地址,10000 就叫高地址。
那么要存一个16位的字,就需要两个内存单元,譬如0和1.
其中低地址存放低位字节,高地址存放高位字节。
譬如 数字 20000(4E20H)
4E是高位字节, 20是低位字节,假如存放在0和1 两个内存单元中。
那么0存放的是20, 1存放的是4E.
读数据是 4E 20
内存 编号是 1 0 。 这里有点反知觉(读数据时 是 4E20, 读编号是0,1,2,3,4,5,有点反过来的感觉)。得换个角度想, 内存编号 从右往左。。数据的字节方向 也是从右往左。
DS和[address]
mov 指令的3类操作
- 直接传递数据给寄存器
mov AX, 30H
- 传递寄存器中的数据到另一个寄存器。
mov AX, BX
- 传递一个内存中的值 到寄存器。
mov AX, [0]
这里说明下:0 表示内存地址偏移量,而段地址自动取DS
寄存器中的值。
mov、add、sub指令
mov指令的形式
可以总结为有4类操作数:
- 普通寄存器
- 段寄存器
- 数据
- 内存
左操作数 | 右操作数 | 示例 | 是否可行 |
---|---|---|---|
普通寄存器 | 普通寄存器 | mov ax,bx | √ |
普通寄存器 | 段寄存器 | mov ax, ds | √ |
段寄存器 | 普通寄存器 | mov ds,ax | √ |
普通寄存器 | 内存 | mov ax, [0] | √ |
段寄存器 | 内存 | mov ds,[0] | √ |
内存 | 普通寄存器 | mov [0],ax | √ |
内存 | 段寄存器 | mov [0],ds | √ |
普通寄存器 | 数字 | mov ax,3 | √ |
段寄存器 | 数字 | mov ax,3 | × |
数字 | 内存 | mov 3,[0] | × |
内存 | 数字 | mov [0], 3 | × |
add,sub类似
数据段
和内存段相似,把一段连续的内存地址用来存放数据,称作数据段,这是编程上的一种安排。
譬如,代码段可以设计为只读的。数据段是可修改的。
栈
后进先出。两种操作:入栈和出栈。
CPU提供的栈机制
8086CPU提供入栈和出栈的指令,最基本的两个是PUSH和POP。
如,push ax
, 把寄存器ax中的数据送入栈中。pop ax
表示从栈中取出数据送入ax。
8086CPU的入栈和出栈操作都是以字 为单位进行的。
段寄存器SS 存放栈顶的段地址。
寄存器SP存放偏移地址。
任意时刻,SS:SP 指向栈顶元素。
8086CPU中,入栈时,栈顶从高地址向低地址方向增长。
栈顶越界的问题
8086CPU不保证我们对栈的操作不会越界。
8086CPU的工作原理,只考虑当前的情况:
- 当前的栈顶在何处。
- 当前要执行的指令是哪一条。
只能程序员自己控制好,避免越界。
push、pop指令
几种形式:
push 寄存器
push 段寄存器
push 内存单元
pop类似。
通过栈可以实现,内存到内存的数据传输。
栈段
和代码段,数据段一样。
栈段也是编程应用。
把一段连续的内存 当做栈来使用。