汇编语言笔记02寄存器
汇编语言笔记02寄存器
0x00 寄存器
一个典型的cpu由 运算器、控制器和寄存器三部分组成,通过内部总线连接在一起。运算器进行信息处理,寄存器进行信息储存,控制器控制各种器件工作。
汇编主要使用寄存器,可以用指令读写,通过改变寄存器的内容对cpu进行控制。
不同cpu寄存器的个数结构种类不同。8086有14个寄存器,名称分别是AX,BX,CX,DX,SI,DI,SP,BP,IP,CS,SS,DS,ES,PSW。
8086所有寄存器都是16位,可以存放两个字节,AX,BX,CX,DX这四个寄存器通常用来放一般性的数据,称为通用寄存器
8086上一代寄存器是8位,为了保证兼容,使原来基于上代的cpu编写的程序稍加修改能够运行在8086上,AX,BX,CX,DX可以分为两个独立的8位寄存器来用
这种低位数据被储存在低地址的存储方式称为小端模式
出于对兼容性的考虑,8086cpu一次性可以处理以下两种尺寸的数据:字节,byte 由8个比特位组成,存放在8位寄存器里;字,word,一个字由两个字节组成,分别称为字的高位字节和低位字节
0x01 几条汇编指令
通过汇编指令,可以操作寄存器
需要注意的是,当al被当做8位寄存器使用时,发生进位不会改变ah,是独立,最高位产生的进位会被丢弃,单是会被进位标志寄存器记录。
在进行数据传送或者运算时,要注意指令的两个操作对象的位数应该是一致的
而且编译器会根据寄存器的位数来自动判断应该从内存读多少个字节:
例如mov ax,[0],由于ax是两个字节16位,所以会从ds:0读两个字节 送到ax里
0x02 物理地址
cpu访问内存单元时,要该出内存单元的地址,所有内存单元构成的储存空间是一个一维的线性空间,每个内存单元在空间中有唯一地址,称为物理地址。
8086cpu是16位cpu,16位cpu指:一次最多处理16位数据,寄存器宽度最大为16,寄存器和运算器的内部总线为16位。
但是8086cpu有20位地址总线,达到1mb寻址能力,但是它本身是16位结构,在内部一次性处理、传输、暂时储存的地址为16位,所以8086采用一种在内部用两个16位地址合成一个20位物理地址的方法
物理地址=段地址*16+偏移地址(也就是将16进制的段地址左移一位加上偏移地址)
0x03 段的概念
内存是连续的,并没有分段,段的划分实际上是8086cpu物理地址的计算方式中的概念,我们根据这个(物理地址=段地址*16+偏移地址)公式可以将内存看成一段一段的。
编程时,根据需要,可以将若干连续的内存单元看作一个段,用段地址16定位段的其实地址(基础地址),用偏移地址定位段中的内存单元。段地址 * 16必然是16的倍数,因此一个段的其实地址必定是16的倍数,用16进制表示时,最低为必定为0,偏移地址为16位,16位的寻址范围为64kb,因此一个段的长度最大为64KB(641024个内存单元)
cpu可以用不同的段地址和偏移地址组合成同一个物理地址
解题思路,物理地址=段地址*16+偏移地址,偏移地址16位变化范围0-0ffffh,
0x04 段寄存器
CS DS SS ES 四个寄存器提供段地址,当8086cpu要访问内存时由这4个寄存器提供内存单元的段地址。
cs和ip是8086cpu中最关键的寄存器,他们指示了cpu当前要读取指令的地址。cs为代码段寄存器,ip为指令指针寄存器。两者合起来提供要读取指令的物理地址。
8086cpu工作过程简化如下:
被cs:ip指向过的地址所储存的信息即是指令,反之位数据
8086cpu大部分寄存器的值可以用mov指令改变,但是cs ip不行,可以用jmp指令修改
jmp 段地址:偏移地址 (同时修改cs ip) 或者 jmp 偏移地址(只修改ip) 同时注意,jmp 偏移地址不能是一个常数(立即数),必须是合法寄存器,也就是不能直接jmp 0 但是可以 mov ax,0 jmp ax
0x05 代码段
上述汇编代码对应的机器码给出,如何让其被cpu执行呢?直接将对应的机器码连续存放在内存中,即为一个代码段,将cs:ip执行该代码段的第一条指令的地址,即可执行该代码段