0 前言
你应该知道8086CPU的物理地址形成方式及其原理,才能完成本文的学习。
1 内存的分段
对于内存,人们人为地将其划分为一段一段的,比如代码段和数据段等,特别注意,这是人为划分的结果,方面人类使用,在物理器件上并不是真正的断开了。
内存的分段就好比这样,人们
- 把代码放在代码段
- 把数据放在数据段
再强调一次,这是帮助人们和汇编语言编译器区分,并不是真的把内存切开,这是虚拟的分段。
1.1 代码段
现在,我们以代码段为例,来学习一些知识。
先给出以下这样一部分汇编指令
mov ax,0000h // 占3个字节
add ax,0123h // 占3个字节
mov bx,ax // 占2个字节
jmp bx // 占2个字节
我们将这样几行代码,称为一个代码段,假设我们使用内存地址123B0H ~ 123B9H来存储它。
对于地址123B0H,我们称之为该代码段的起始地址,它必须是16的整倍数,它对应的段地址是123BH。
该代码段的长度为10个字节。
我们先介绍这些,请继续往下看。
2 CS:IP
CS:Code Segment(代码段寄存器)
IP:Instruction Pointer(指令指针寄存器)
这两个寄存器都是16位的,由CS提供段地址,这个段地址对应上一小节的123BH,由IP提供偏移地址。
CS:IP的意义是,将两个16位的地址,在CPU内部合成为20位地址,并输出到外部,CS:IP合成的地址是对于内存地址的,比如上一小节的123B0H,其公式是合成地址 = CS*16 + IP
,比如123B0H = 123BH*16 + 0H
CS:IP所指向的内存地址,代表这个内存地址所存储的二进制信息是指令,然后会进入CPU执行该指令。
3 代码段与CS:IP的联系
这里给出了CS:IP、内存地址、代码段和汇编指令之间的对应关系,建立起了CPU和内存之间的联系。
本文并不讲解CS:IP的原理,是帮助你加深理解内存和CPU操作之间的关系。
这里重点强调:
- 先确定CS:CS寄存器存储的是段地址,左移一位后(乘16),对应的是代码段的基础地址
- 再确定IP:IP寄存器存储的是段内偏移地址,偏移地址是在基础地址的基础上,进行偏移,以便于执行代码段中的各个指令。
需要注意的是,代码段,以及其他段,最大的段长等于IP的最大值,这里是16位,也就是一个段最大2^16B = 64KB。
4 段地址和偏移地址的本质
段地址有两重含义:
- 段寄存器(例如CS)储存的地址:例如123BH
- 某一内存段(例如代码段)的起始地址:例如123B0H
偏移地址,更本质的说法是段内偏移地址,这里的段内含义的某一代码段内,例如上述实例
- 偏移0H,执行
mov ax,0000h
- 偏移3H,执行
add ax,0123h
- 偏移6H,执行
mov bx,ax
- 偏移8H,执行
jmp bx
5 镜像迁移——掌握其他类型
对于类似的操作及其对应关系,模式都一样!,就好比
- 国家之下有省
- 省之下有市
- 市之下有县
整体来看,同一层级的管理模式整体来说,是一样的。
这里我需要说明,寄存器的能力是一样的,就是暂存数据,只不过其分工不同,做的事情不同,但是因为其能力一样,因此只需要掌握一种模式,就可以进行快速复制。
我们需要做的是,学好一个内容,然后使用镜像迁移的能力,复制成功的模式,这样你就快速学会各种汇编操作。
你会发现,以下内容,你能够快速掌握!
这里我直接引用了一个表格,请读者按照CS:IP的模式,自行完成学习,这里有一个可替换段地址,请自行查阅资料,这也是必备的能力。