实模式下cpu寄存器
Intel CPU8086 实地址模式:CPU加电或者重启的时候自动进入的工作模式
1、CPU内的寄存器:都是16位的。汇编程序员使用这些寄存器有很多限制。
(1) 通用寄存器:
AX、BX、CX、DX。做算术和逻辑运算。
它们都可以分成两个8位的寄存器使用:AH、AL、BH、BL、CH、CL、DH、DL。(H:high,L:low)
(2)基地址寄存器(简称基址):
BX、BP。其中BP专门用于访问堆栈段Stack。
(3)变址寄存器:
SI、DI。SI:Source Index源变址寄存器;DI:Destination Index 目标变址寄存器。
一般存放段内的偏移地址。
(4)标志寄存器EFlags或者程序状态字PSW(program Status Word):
存储程序的运算结果的状态信息。
状态信息:XF :结果为0吗? CF:有没有进位? OF:有没有溢出?IF:允许中断吗?
该寄存器不能整体引用,只能引用相应的单独的位。例如指令JZ:Jump if Zero(结果为0则跳转)。
(5)段寄存器:
CS、DS、ES、SS、FS、GS:存放内存段的起始地址。
实模式下内存物理地址为20位地址,但一个内存段它的起始地址必须起始于(x....xxx 0000)16位x加上4位0。写成十六进制必须为xxxx0H,然后将该内存段的起始物理地址的高十六位装入到段寄存器中,称为段地址。
(6)SP 与 IP:
Stack Pointer 堆栈指针寄存器,永远指向堆栈的栈顶(SP存放的是栈顶单元的偏移地址)
IP:Instrcution Pointer指令指针寄存器,永远指向马上要取的下一条指令(IP存放的是下一条要执行指令的偏移地址)。CS:IP就永远指向马上要执行的下一条指令。CS:Ip就是实模式下的程序计数器PC(program Computer)
BIOS:Basic Input Output System(基本输入输出系统,存放了基本的硬件驱动程序,如键盘,鼠标,显卡等)。
可以写5个字节的一个程序reset.com重启电脑(dos操作系统),程序内容就一条指令:JMP FFFF:0 或者CALL FFFF:0
实模式下内存段长度最长为16K(2的16次方),最小可以是1字节。
内存段的性质:CS:Code Segment代码段段地址;DS:Data Segment数据段段地址;SS:Stack Segment堆栈段段地址;ES:Extra Data Segment附加数据段段地址;FS和GS里存放另外两个附加数据段段地址
计算机基本工作过程:
在实模式下,CPU加电或重启时,自动初始化CS为全1,IP为全0,即CS = FFFFH,IP = 0000H,所以实模式下CPU加电执行的第一条指令的物理地址为FFFF0H。在此处存放了一条无条件跳转指令,跳到上电自检程序POST(Power On Self Test),post程序在ROM中(BIOS芯片中)。
如果post通过,没有问题,则在活跃磁盘分区上加载引导程序boot(小于512字节),然后通过boot引导程序加载操作程序的内核代码,然后再加载shell程序(操作系统的界面程序,如命令行界面或图形界面),然后这个shell程序就循环等待用户输入待执行的程序,分析执行程序(有的是shell自己执行,称为内部命令,有点则需要内核加载程序执行,称为外部命令)。重复这个过程,直到断电或遇到停机指令halt为止。
2、内存中的存储单元(地址空间):实模式只能寻址2的20次方,即1MB。物理地址为20位,段内偏移地址(也称为有效地址)为16位
逻辑地址:段地址:偏移地址。 物理地址:段地址*16 + 偏移地址
3、I/O 端口:16位的端口地址。每个端口代表某个外部设备(I/O设备)控制接口卡中的寄存器(数据、状态、控制)。
4、程序的内存映像:代码段/文本段、全局数据段、栈、堆
5、实模式下能用的指令:CPU的指令集(指令系统:Instruction Set)
指令的基本格式:1、操作码operator(告诉cpu做什么运算?);2、操作数operand(待加工的数据在哪儿?运算结果存哪儿?)
根据指令中操作数的个数,可以把指令分为如下几类:
(1) 零操作数指令:
有的是没有操作数,有的是隐含操作数。比如halt停机指令,nop没有操作数,ret子程序返回指令。
(2) 单操作指令:
只有一个操作数或者有两个操作数但其中一个是隐含的。
(3)双操作数指令:
有两个操作数,其中第一个称为目的操作数,第二个称为源操作数。
运算符 目的操作数,源操作数 (Intel风格的汇编指令)
运算符 源操作数,目的操作数 (Linux下AT&T风格的汇编指令)
功能:目的操作数 <=== (目的操作数 , 运算符,源操作数)
例如: mov si,48 类比:int x = 0x30;