1 基础知识
汇编语言产生于机器语言的过于复杂和难以记忆。
汇编指令通过编译器编译为机器码后,计算机才可以理解。
2 寄存器:CPU工作原理
2.1 通用寄存器
16位寄存器可以放两个字节。AX BX CX DX通常被用来存放一般性的数据,被称为通用寄存器。
AX:由低到高填入二进制数,空位补零。
16位寄存器储存的最大数:2^16-1。
存在8位寄存器,为了兼容8位寄存器,一个16位的寄存器可以分为两个独立的8位寄存器使用。AX可以分为AH(high)高地址和AL(low)低地址。
2.2 字在寄存器中的存储
一个字占两个字节,一个字节8位。一个内存单元是8位。
2.3 几条汇编指令
语法:不分大小写。
mov ax,18:将18这个值赋给ax寄存器。 ax = 18
add ax,8:将ax中的数值+8。 ax += 8
add ax,bx:将ax,bx中的内容相加,结果存在ax中。
如果相加的结果大于16位,多出部分会放到别的地方。
2.4 物理地址
cpu访问内存单元时要给出内存单元的地址,所有的内存单元构成的存储空间是一个一维的线性空间。这个唯一的地址称为物理地址。
2.5 16位的cpu
16位cpu具有一下三方面的特点:
运算器以此作多可以处理16位的数据。
寄存器的最大宽度是16位。
寄存器和运算器之间的通路是16位。
(且cpu位数等于数据总线的条数)
2.6 8086cpu给出物理地址的方法
8086的地址总线位20位,内部位16位,寻址能力并不相同。它采用了一种在内部用两个16位地址合成的方法来形成一个20位的物理地址。
16位段地址 + 16位偏移地址 –> 经过地址加法器 –> 生成20位地址
具体过程:段地址*16(16进制左移一位),在于偏移地址相加,得到20位地址。
生成同一个地址,可能有多种段地址和偏移地址的组合。
2.7
2.8 段的概念
在编程时可以根据需要,将若干地址连续的内存单元看作一个段,用段地址*16定位段的起使地址(基础地址),用偏移地址定位段中的内存单元。
- 段地址*16必然是16的倍数,所以一个短的起始地址也一定是16的倍数;
- 偏移地址位16位,16位地址的寻址能力位64K,所以一个段的长度最大为64K。范围为:0~FFFFH。
2000段中的1F60H单元 = 2000:1F60单元。
2.9 段寄存器
CS(code segment) 代码段寄存器:
DS(data segment) 数据段寄存器
SS(stact segment) 栈段寄存器
ES(extra segment) 额外段寄存器
为8086的4个段寄存器。当8086要访问内存时,由这4个段寄存器提供内存的单元的段地址。
2.10 CS和IP
CS(code segment) 代码段寄存器:
指示了cpu当前要读取指令的地址。
CS为代码段寄存器。
IP为指令指针寄存器(偏移寄存器)。
步骤:
- 从CS:IP指向内存单元读取指令,读取的指令进入指令缓冲器(准备执行);
- IP = IP + 读取指令的长度,从而指向下一条指令;
- 执行指令,回到步骤1,重复。
8086pc工作的简要描述:
- 在加电启动或复位后,CS和IP被设置为CS=FFFFH,IP=0000H;
- cpu从内存FFFF0H单元中读取指令执行。
- FFFF0H端元中的指令是8086开机后执行的第一条指令。
如果说,内存中的一段信息曾被cpu执行过,那么它所在的内存单元必定被CS:IP指向过。
2.11 修改CS IP的指令
程序员可以通过使用jmp指令改变CS IP中的内容控制cpu执行的目标指令。
jmp 2000:2AE3
:修改CS和IP。
jmp ax
:将ax的值赋给IP,只修改IP的值。
2.12 代码段
可以将长度小于64K的一组代码,存在一组地址连续、起始地址为16的倍数的内存单元中,这段内存用来存放代码,从而定义了一个代码段。
只有被CS:IP指向的内存单元中的内容才会被cpu认为是指令。用DS会被理解为数据。
要将CS:IP指向代码段的第一条指令。
3 寄存器:内存访问
3.1 内存中字的存储
一个地址单元放一个字节,8位。一个字型数据站两个字节,也就是两个地址单元。
任何两个地址连续的内存单元,n号单元和n+1号单元,可以将它们堪称两个内存单元,也可以看成一个地址为n的字单元中的高位字节单元和低位字节单元。
3.2 DS和[address]
1 | # 将字节数据从内存单元送入寄存器 |
ds中的1000H是段地址,[ ]中是偏移地址。上面三条指令将1000:0中的数据读到al中。
- 不可以直接给ds段寄存器赋值。
- 在从内存中取值之前,在ds里设置好段地址,取值时用[ ]写偏移地址。
1 | # 将字节数据从寄存器送入内存单元 |
3.3 字的传送
1 | mov bx,1000H; |
3.4 mov、add、sub指令
mov指令的几种形式:
- mov 寄存器,数据
- mov 寄存器,寄存器
- mov 寄存器,内存单元
- mov 内存单元,寄存器
- mov 段寄存器,寄存器
- mov 寄存器,段寄存器
add和sub指令同mov一样,都有两个操作对象。但是它们两个不可以操作段寄存器。因为段寄存器无法进行四则运算。
3.5 数据段
可以根据需要将一组内存单元定义为一个段(可以是代码段、数据段等)。必须是16的倍数。
3.6 栈
栈是一种具有特殊访问方式的数据存储空间。先进后出。
3.7 cpu提供的栈机制
PUSH(入栈)ax:将寄存器ax中的数据送入栈中。
POP(出栈)ax:从栈顶取出数据ax。
cpu如何找到栈顶元素的位置?通过SS:SP找到栈顶元素的地址。
PUSH的过程:SP = SP - 2,然后将数据送入SP指向的内存单元处。
POP的过程:将SP指向位置的数据取出来,然后SP = SP + 2。
空栈时,SP指向最高地址单元的下一个地址。