汇编(2)- 访问指令
1)CPU的组成
CPU的组成部分主要有运算器、控制器、寄存器和内部总线,内部总线连接所有这几个器件,运算器负责数据的运算信息处理,寄存器负责存储数据,控制器负责控制外部设备的工作。
汇编语言的主要工作是控制寄存器,改变寄存器中的内容来实现控制CPU。
不同的CPU核心架构,其寄存器的种类和数量也不同,寄存器也都有规定的容量,例如8086的寄存器,其容量是16位。
一个16位的寄存器最大可存储多大的数?
答:2^16-1=65535
一个16位寄存器,可以存储一个字,高8位和低8位分别存储一个字节。而这个字在内存中的存储则是另一种情况,因为存储单元只能存放一个字节,所以需要连续两个存储单元存放一个字,低字节存放到低地址单元,高字节存放到高地址单元。
2)物理地址
CPU要访问一个内存单元,则必须要先给出这个内存单元的地址,前文已经说过,计算机的内存地址空间是一个一维线性空间,每个内存单元都有一个唯一的地址,这个唯一的地址就是物理地址。
CPU必须通过地址总线将内存单元的物理地址告知存储器,在发送物理地址之前CPU内部必须先形成这个物理地址,不同的CPU有不同的方式形成物理地址。
以8086CPU为例,8086CPU是16位结构的CPU,16位结构的意义是:
- 运算器最多可以处理16位数据
- 寄存器最大宽度是16位
- 寄存器和运算器之间的数据宽度是16位
8086CPU具有20位数据总线(最大寻址空间是1MB),但是CPU内部的数据传输宽度却是16位,所以不能简单的一次性将地址发送出去,因为16位最大只能寻址64KB,必须先由CPU内部先形成一个20位的物理地址后再发送给内存地址空间。
- CPU提供两个16位地址:段地址和偏移地址
- 有一个称为地址加法器的器件进行运算得到20位的物理地址
- 20位物理地址最后传送到存储器
地址加法器所用到的物理地址计算公式是:
物理地址=段地址*16+偏移地址
乘以16意味着左移4位,也就刚好形成了20位物理地址了。
3)段地址
上面的公式可以再次整合成:
物理地址=基础地质+偏移地址。
使用这种方式给出物理地址的动机是CPU将内存地址空间划分成若干个段,使用分段的方式管理内存的好处,一个很小的段地址和一个很小的偏移地址可以组合成一个很大的物理地址。
4)段寄存器和指令
8086有4个存放段地址的段寄存器,分别是CS、DS、SS和ES。
CS和IP是8086CPU取指令的关键器件,CS是代码段寄存器,存放的是代码段的起始地址,IP是指令指针寄存器,是指令的偏移地址,两者组成的就是指令的存储地址了。
取指令并执行指令的过程是:
- 将CS:IP指向的指令取出放入指令缓存器
- IP += 所读取指令的长度,从而指向下一条指令
- 执行指令,然后回到第1步,重复该过程
前面说过,不管是指令还是数据,在存储器中的格式都是二进制机器码,那么怎么区分CPU取得的是数据还是指令呢?现在有答案了,CS:IP指向的就是指令,因为CS寄存器存放的是指令的段地址,IP寄存器存放的是指令的偏移地址。
若想通过汇编指令手动的修改CS:IP指向的物理地址,则必须使用8086提供的专用的指令jmp。
jmp 1000H:0003H
该汇编指令的意思是:将CS的内容改成1000H,将IP的内容改成0003H。
jmp AX
该汇编指令的意思是:将AX中的内容用来修改IP中的内容。
5)代码段
所谓的代码段,就是起始地址为16的倍数的一段地址连续的内存空间段,其用处是存放一段不大于64KB(因为偏移地址是16位的)的代码。
例如以下一段代码:
mov ax, 0000 (B8 00 00)
add ax, 0123 (05 23 01)
mov ax, bx (8B D8)
jmp bx (FF E3)
该段代码占用10字节空间,假如被存放到123B0H~123BAH内存单元中,就可以认为该段内存单元组成了一个代码段,段地址为123BH,长度为10字节。接下来要执行该段代码,就要将指令指针指向该段的首地址:
jmp 123BH:0000H
汇编(2)- CPU的工作原理
【参考】
https://www.jianshu.com/p/0cfcf7cddbb5
《汇编语言》-王爽