网站首页 > 精选教程 正文
摘要
- 寄存器
- 实模式下的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的寻址方式就介绍到这,“点赞”+“关注”,我们下期再见!
- 上一篇: java基础之使用线程池并获取执行结果
- 下一篇: Java 插入、提取Excel中的OLE对象
猜你喜欢
- 2025-03-12 Java开发5年,四面美团(多线程+JVM+数据库),终拿offer!
- 2025-03-12 Java 插入、提取Excel中的OLE对象
- 2025-03-12 java基础之使用线程池并获取执行结果
- 2025-03-12 2020年Java全套学习路线,月薪两万不是梦
- 2025-03-12 java输入天数计算几周且剩余几天
- 2025-03-12 量化交易第一步,利用java获取交易实时数据
你 发表评论:
欢迎- 04-11Java面试“字符串三兄弟”String、StringBuilder、StringBuffer
- 04-11Java中你知道几种从字符串中找指定的字符的数量
- 04-11探秘Java面试中问的最多的String、StringBuffer、StringBuilder
- 04-11Python字符串详解与示例(python字符串的常见操作)
- 04-11java正则-取出指定字符串之间的内容
- 04-11String s1 = new String("abc");这句话创建了几个字符串对象?
- 04-11java判断字符串中是否包含某个字符
- 04-11关于java开发中正确的发牌逻辑编写规范
- 最近发表
-
- Java面试“字符串三兄弟”String、StringBuilder、StringBuffer
- Java中你知道几种从字符串中找指定的字符的数量
- 探秘Java面试中问的最多的String、StringBuffer、StringBuilder
- Python字符串详解与示例(python字符串的常见操作)
- java正则-取出指定字符串之间的内容
- String s1 = new String("abc");这句话创建了几个字符串对象?
- java判断字符串中是否包含某个字符
- 关于java开发中正确的发牌逻辑编写规范
- windows、linux如何后台运行jar(并且显示进程名)
- 腾讯大佬私人收藏,GitHub上最受欢迎的100个JAVA库,值得学习
- 标签列表
-
- nginx反向代理 (57)
- nginx日志 (56)
- nginx限制ip访问 (62)
- mac安装nginx (55)
- java和mysql (59)
- java中final (62)
- win10安装java (72)
- java启动参数 (64)
- java链表反转 (64)
- 字符串反转java (72)
- java逻辑运算符 (59)
- java 请求url (65)
- java信号量 (57)
- java定义枚举 (59)
- java字符串压缩 (56)
- java中的反射 (59)
- java 三维数组 (55)
- java插入排序 (68)
- java线程的状态 (62)
- java异步调用 (55)
- java中的异常处理 (62)
- java锁机制 (54)
- java静态内部类 (55)
- java怎么添加图片 (60)
- java 权限框架 (55)
本文暂时没有评论,来添加一个吧(●'◡'●)