1基础知识
机器语言是机器指令的集合,由0和1组成,但是很长很复杂,汇编语言因此产生。
汇编语言的主体是汇编指令。汇编指令是机器指令的便于记忆的书写格式。
程序员写完汇编指令通过编译器转换为机器码,机器码再传到计算机执行。
汇编语言有以下三类:
1汇编指令:助记符,有对应机器码
2.伪指令:没有对应机器码,编译器执行计算机不执行
3.其他符号:+ -等由编译器识别,没有对应机器码
汇编语言的核心是汇编指令,决定了汇编语言的特性
CPU是计算机的核心部件,他控制整个计算机的运作并运算,指令和数据在存储器中存放,也就是内存。CPU离不开内存。内存中指令和数据没区别,都是二进制。CPU来识别是信息还是指令。
一个存储单元存储1Byte
CPU从内存中读写书,要指定地址,指定进行哪种操作,CPU通过总线连接其他芯片,传输信息
存储单元的地址(地址信息)->地址总线
器件的选择,读或写的命令(控制信息)->控制总线
读或写的数据(数据信息)->数据总线
]()
地址总线
一根导线有两种稳定状态代表0和1,那么10根导线就有2^10次方个不同数据,从0到1023
地址总线的宽度决定了CPU的寻址能力
数据总线
8根数据总线可传送一个8位二进制数据 8bits = 1byte
数据总线的宽度决定了CPU与其他器件进行数据传送时的一次数据量
控制总线
控制总线的宽度决定CPU对外部器件的控制能力
主板上都是核心器件,CPU、存储器等,CPU通过总线向接口卡发送指令,接口卡控制外设进行工作
随机存储器RAM 只读存储器ROM
BIOS(Basic input/putput system)
CPU将各类存储器看作一个逻辑存储器,所有的物理存储器被看作一个由若干个存储单元组成的逻辑存储器,每个物理存储器在这个逻辑存储器中占有一个地址段,即一段地址空间。
内存地址空间的大小受CPU地址总线宽度的限制。不同计算机系统内存地址分配情况不同
2.寄存器
CPU由运算器、控制器、寄存器等器件构成,器件靠内部总线连,与之前总线(外)不同
寄存器程序员可以用指令读写
8086CPU的14个寄存器
AX、BX、CX、DX、SI、DI、SP、BP、IP、CS、SS、DS、ES、PSW
通用寄存器:
用来存放一般性数据 AX BX CX DX
16位寄存器可以拆成两个8位寄存器使用 AH AL,高8位和低8位
两字节byte构成一个字word,一个字节8bit放在8位寄存器
汇编指令
mov ax,18
mov ah,78
add ax,8
mov ax,bx
add ax,bx
...
16位寄存器只能存放4位十六进制数据,1044CH最高位的1就不能保存再ax中004CH
独立使用AL这个寄存器如果进位是不会储存在AH中
数据传送和运算时 指令的两个操作对象的位数应当一致
物理地址
所有内存单元构成的存储空间是一个一维的线性空间,每一个内存单元在这个空间中都有唯一的地址
CPU向地址总线发出物理地址前,要在内部形成这个物理地址
16位的CPU能够一次性处理、传输、暂时存储16位地址
8086CPU有20位地址总线,内部用两个16位地址合成一个20位 的物理地址
物理地址 = 段地址 x 16(基础地址) + 偏移地址
段地址 x 16 常用说法左移4位(二进制位)相当于16进制左移1位
X 进制左移1位相当于乘 X
因为内部结构是这样,为了达到20位寻址能力,利用两个16位地址可以达到目的
接着段地址,内存没有分段,段的划分来自cpu
段地址 x 16是16的倍数,所以一个段的起始地址也是16的倍数;偏移地址位16位,16位地址的寻址能力位64kb,所以一个段的长度最大为64kb
CPU可以用不同的段地址和偏移地址形成同一个物理地址
8086的4个段寄存器CS、DS、SS、ES。当访问内存由这四个段寄存器提供内存单元段地址
CS为代码段寄存器 IP为指令指针寄存器
任意时刻,设CS内容为M,IP中内容为N,8086CPU从内存M x 16 + N单元开始,读取指令并执行
读取一条指令后,IP中的值自动增加(指令长度),以使CPU可以读取下一条指令
CPU将CS:IP指向的内存地址单元内容看作指令
同时修改CS、IP的内容可以用 jmp 段地址 :偏移地址
仅修改IP可用 jmp 某一合法寄存器(用寄存器中的值修改IP)?
8086机编程时,可以根据需要,将一组内存单元定义为一个段。
将长度为N<=64的代码,存在一组地址连续、起始地址为16的倍数的内存单元作代码段
用CS:IP指向的内容就能让代码段的内容执行
3.寄存器(内存访问)
在内存中存储时,内存单元是一个字节byte单元,则一个字Word要用两个地址连续的内存单元来存放,低位字节存放在低地址单元,高位字节存放在高地址单元
字单元:由两个地址连续的内存单元组成,起始地址为N的字单元简称为N地址字单元
0地址字单元4E21H,1地址字单元124EH......
DS和[address]
8086中有一个DS寄存器,通常用来存放要访问数据的段地址
mov bx,1000H
mov ds,bx
mov al,[0]
将10000H(1000:0)中的数据读到al中
这里[...]表示一个内存单元,括号里面表示偏移地址,指令执行时8086CPU自动读取ds中数据作为内存单元的段地址
8086CPU不支持将数据直接送入段寄存器,只好用一个寄存器中转
16位结构,有16根数线,所以一次可以传送16位数据,也就是一个字
mov add sub都是带有两个操作对象的指令,而jump具有一个
编程时根据需要定义数据段,可以在具体操作的时候用ds存放数据段的段地址,再根据需要,用相关指令访问数据段中的具体单元
栈
栈是一种具有特殊访问方式(最后进入空间的数据,最先出去)的存储空间
栈的两个基本操作:入栈和出栈,入栈就是将新的元素放到栈顶,出栈就是将栈顶元素取出一个
栈的操作规则被称为:LIFO(Last In First Out,后的进先出来)
编程时,可以将一段内存当作栈
push ax 将ax中数据入栈
pop ax 从栈顶取出数据到ax
操作都是以字为单位进行的
8086CPU中任意时刻,段寄存器SS(栈的段地址):寄存器SP(偏移地址)指向栈顶元素,push指令和pop指令执行时,CPU从SS和SP中得到栈顶地址
push ax两步走
1> SP=SP-2,SS:SP指向当前栈顶前面的单元,作为新栈顶
2> 将ax中的内容送入SS:SP指向的内存单元处,SS:SP此时指向新栈顶
入栈时,栈顶从高地址向低地址方向增长。
pop ax两步走
1> 将SS:SP指向的内存单元处数据送入ax
2> SP=SP+2,SS:SP指向当前栈顶下面的单元,作为新的栈顶
值得注意的时,出栈后pop操作前的栈顶元素仍然存在,但是它已经不在栈中,再次push后会在那里写入新数据覆盖
由上面数据不在栈中进而可以思考栈顶超界的问题
8086CPU不保证我们对栈的操作不会超界
当我们把一段内存当作栈空间,当栈满时再执行push栈顶超出栈空间,栈空间外数据被覆当栈空时再次执行pop栈顶超出了栈空间,而超出的地方的数据会被覆盖,自己需要注意
用栈暂存以后需要恢复寄存器中的内容时,出栈顺序和入栈顺序相反
push和pop实质上是一种内存传送指令
编程时根据需要可定义栈段
段的综述
对于数据段,将它的段地址放在DS中,用mov、add、