网站首页 > java教程 正文
摘要
- 寄存器
- 实模式下的CPU寻址方式
- 寄存器寻址
- 立即数寻址
- 内存寻址
- 栈
1. 寄存器
寄存器是一种物理存储原件,速度可以跟上CPU的速度,所以CPU内部使用各种类型的寄存器供读取数据来使用。这里可以看出寄存器的主要用途:
- 为CPU存储数据
- 解决从其他硬件获取数据与CPU执行速度不匹配的问题
CPU中的寄存器大致分为两类:
- 内部使用,对程序员不可见(不可使用):GDTR(全局描述符表寄存器)、IDTR(中断描述符表寄存器)、LDTR(局部描述符表寄存器)、TR(任务寄存器)、CR0~3(控制寄存器)、(IP)指令指针寄存器、flags(标志寄存器)、DR0~7(调试寄存器)
- 程序员可见(可以直接操作)的寄存器:段寄存器、通用寄存器
实模式下默认用到的寄存器都是16位。
1.1 内部寄存器
内部寄存器虽然不可以直接使用,但是部分寄存器必须要通过我们的代码进行初始化。
- GDTR需要通过lgdt指令为其指定全局描述符表的地址及偏移量
- IDTR需要通过lidt指令为其指定中断描述符表的地址
- LDTR需要通过lgdt指令为其其指定局部描述符表ldt
- TR需要通过ltr指令为其指定一个任务状态段tss
1.2 可见寄存器
1.2.1 段寄存器
段寄存器是CPU用来寻址使用,CPU默认的寻址方式是**"段基址":"段内偏移地址"**,段基址就是用段寄存器来进行存储。
在我们计算机加载我们的程序以后,会将我们的应用程序在内存大致分为三个部分:
- 代码段:该内存区域存储了我们应用程序的指令
- 数据段:该内存区域存储的是我们需要使用到的数据
- 栈段:CPU运行时的必须
段寄存器主要由以下分类:
- CS(代码段寄存器):存储代码段的起始地址
- DS(数据段寄存器):存储数据段的起始地址
- SS(栈段及寄存器):存储栈的起始地址
- ES、CS、GS(附加段寄存器)
可见寄存器CS:内部寄存器IP存储了CPU下一条待执行指令的地址。
1.2.2 通用寄存器
通用寄存器主要由以下几类组成:
- AX(累加器):由低8位的AL寄存器和高8位的AH寄存器组成,常用于算数运算、逻辑运算、保存外设输入输出的数据
- BX(基址寄存器):由低8位的BL寄存器和高8位的BH寄存器组成,常用于存储内存地址,用此地址作为基址遍历一片内存区域
- CX(计数器):由低8位的CL寄存器和8位的CH寄存器组成,常用于计数(循环指令中的循环次数)
- DX(数据寄存器):由低8位的DL寄存器和高8位的DH寄存器组成,常用于保存外设控制器的端口号地址
- SI(源变址寄存器):常用于字符串操作中的数据源地址(被传送的数据在哪里)
- DI(目的地址寄存器):常用于字符串操作中的数据目的地址(数据被传送到哪里)
- SP(栈指针寄存器):段基址寄存器是SS,用来指向栈顶。push和pop会修改SP的值
- BP(基址指针):SP永远指向栈顶,我们无法访问栈顶和栈底之间的数据,如果想要访问这期间的数据就需要借助SS:BP
2. 实模式下的CPU寻址
指令都是由操作码和操作数组成,操作数可以是源操作数、目的操作数,寻址就是寻找操作数的地址。
寻址的方式主要分为以下三类:
- 寄存器寻址
- 立即数寻址
- 内存寻址
2.1 寄存器寻址
只要牵涉到寄存器的操作,无论是源操作数还是目的操作数,都是寄存器寻址。
; 将0x10存入ax寄存器
mov ax, 0x10
;将0x9存入dx寄存器
mov dx, 0x9
;求ax和dx的乘积,高16位在dx寄存器,低16位在ax寄存器
mul dx
这三条命令都属于寄存器寻址。
2.2 立即数寻址
指令都是由操作码和操作数组成,如果操作数可以直接存在指令中,拿过来即可使用,那么该数成为立即数。
mov ax, 0x10
mov dx, ax
第一条命令的源操作数是0x10,目的操作数是ax寄存器,所以第一条命令即是寄存器寻址又是立即数寻址。
第二条命令只涉及到寄存器,因此它只是寄存器寻址。
2.3 内存寻址
寄存器寻址和立即数寻址中,源操作数和目的操作数不在内存中。相反操作数在内存中的寻址方式则称为内存寻址。
实模式下CPU访问内存采用的是段基址:段内偏移的形式,计算方式是 物理地址 = 段基址*16(相当于左移4位) + 段内偏移地址,默认情况下,数据段寄存器是DS。
内存寻址的方式主要有:
- 直接寻址
- 基址寻址
- 变址寻址
- 基址变址寻址
2.3.1 直接寻址
直接寻址就是将操作数的内存地址在指令中直接给出。
mov ax, [0x1234]
mov ax, [fs:0x5678]
第一条指定是将内存地址为(DS*16 + 0x1234)的值写入ax寄存器。
第二条指定是将内存地址为(FS*16 + 0x5678)的值写入ax寄存器。
2.3.2 基址寻址
基址寻址是指操作数用BX寄存器或BP寄存器作为地址的开始,地址的变化都以其为基础。实模式下只能使用BX或BP寄存器作为基址,保护模式下则无这种限制。
BX寄存器的默认段寄存器为DS,BP寄存器的默认段寄存器为SS。
int a = 0;
function(int b, int c) {
int d;
}
a++;
2.3.3 变址寻址
变址寄存器类似于基址寄存器,寄存器由BX、BP换成了SI、DI。SI是指源索引寄存器、DI是指目的索引寄存器。默认的端寄存器都是DS。
mov [di], ax
mov [si+0x1234], ax
第一条指令是将寄存器AX中的值存入DS:DI指向的内存地址处。
第二条指令是将寄存器AX中的值存入DS:(DI+0x1234)指向的内存地址处。
2.3.4 基址变址寻址
基址变址寻址就是采用基址变址+变址寻址的组合。如下:
mov [bx+di], ax
该条指令的含义就是将寄存器AX中的值存入DS:(BX+DI)指向的内存地址处。
3. 栈
栈是一种什么数据结构这里就不说了,我们这里讲的栈是一片内存区域,栈中的内存地址也是采用段寄存器SS中的值*16 + 栈指针寄存器SP来访问。
硬件提供了相应的方法来存取栈,即PUSH和POP指令。
栈是从高地址往低地址发展,因此栈顶的指针指向的地址会越来越低。
我们在访问栈的时候,访问的内存依然是从低地址到高地址,假设当前栈顶是0x1233E,栈顶数据如果占2字节的话,则范围是0x1233E~0x1233F。
PUSH指令压入数据的过程:
- 将SP减去字长(CPU一次可处理的数据长度,实模式下为16位)
- 所得的差存入SP,栈顶更新完成
- 将数据压入SP所指向的内存地址处
POP指令弹出数据的过程:
- 弹出栈顶的数据(SP指向的内存地址)
- 将SP加上字长
- 所得的和存入SP,栈顶更新完成。
本期寄存器及实模式下CPU的寻址方式就介绍到这,“点赞”+“关注”,我们下期再见!
猜你喜欢
- 2025-04-30 多种负载均衡算法及其Java代码实现
- 2025-04-30 输入www.baidu.com背后经历了啥?说清楚这个,已经超过90%的人了
- 2025-04-30 优化MySQL:为什么你应该用 UNSIGNED INT 存储IP地址
- 2025-04-30 java基础都在这了,小主们拿去吧(java基础是指什么)
- 2025-04-30 盘点爬虫语言为何选择Python而不是Java
- 2025-04-30 搭载Dubbo+Zookeeper踩了这么多坑,我终于决定写下这篇
- 2025-04-30 网络协议之TCP/IP协议(面试必考内容) - javaEE初阶 - 细节狂魔
- 2025-04-30 深夜报警!10亿次请求暴击,如何用Redis找出最热IP?
- 2025-04-30 VPN技术(IPsec/L2TP/SSLVPN/PPTP)学习笔记
- 2025-04-30 74块钱一年的云服务器可以用来做什么?
你 发表评论:
欢迎- 最近发表
-
- 多种负载均衡算法及其Java代码实现
- 输入www.baidu.com背后经历了啥?说清楚这个,已经超过90%的人了
- 优化MySQL:为什么你应该用 UNSIGNED INT 存储IP地址
- 实模式下CPU如何获取数据及指令(实模式寻址方式)
- java基础都在这了,小主们拿去吧(java基础是指什么)
- 盘点爬虫语言为何选择Python而不是Java
- 搭载Dubbo+Zookeeper踩了这么多坑,我终于决定写下这篇
- 网络协议之TCP/IP协议(面试必考内容) - javaEE初阶 - 细节狂魔
- 深夜报警!10亿次请求暴击,如何用Redis找出最热IP?
- VPN技术(IPsec/L2TP/SSLVPN/PPTP)学习笔记
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)