`
pleasetojava
  • 浏览: 729966 次
  • 性别: Icon_minigender_2
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

一个地址的旅程

 
阅读更多
The Trip of An Address -- An Outline
Jason Lee

[Scene 1. Code -> VA]
本文将以如下代码(ttoaa.c)为例,观察函数f入口地址的行程。
整篇文章的内容会涉及Linux和Windows两种不同系统的场景。
将以上代码在Windows上进行编译、链接,得到ttoaa.exe,运行输出:
由此可知道函数f的VA为0x00401000。那么,这个VA是怎么来的?
通过执行命令dumpbin /ALL ttoaa.exe > ttoaa.exe.dump,可以得到PE文件格式内容。
在Optional Header Values中可以看到image base为0x00400000,而base of code为1000,
所以可以知道代码段的起始位置为0x00401000,而函数f正好位于代码段起始位置。
参考ttoaa.exe.dump文件的内容,可以想象这个程序在内存中的布局可能如下图:

[ 图 - 1 ]

[Scene 2.TLB]
关于TLB的位置,我有点小疑惑:是在Segmentation之前还是之后呢?
后来我想,不论是从TLB的实际作用(VA -> PA),还是从目的(加快地址映射)来看,都应该在Segmentation前面。

现在获得了函数f的VA,CPU要执行相应代码,首先要获取第一条指令。
怎么获取这一条指令呢?首先看main函数:

前面就知道main函数的入口地址为0x00401020,从反汇编结果可以看出一进入main函数先保存栈顶指针,继而调用函数f。
现在CPU需要做的就是获取VA为0x00401000的指令,然后执行。

[ 图 - 2 ]
如上图,CPU的取指(Fetch)阶段会先访问TLB,看是否存在VA到PA的映射。
并且由于现在要获取的是指令,所以对应的是i-TLB,即Instruction TLB。
TLB全称为Translation Lookaside Buffer,存储着key-value映射,其中key为VA,value为PA。
由于是第一次访问0x00401000,所以i-TLB中还没有相关映射,需要继续进行地址映射,并把映射结果回填到i-TLB,以加速下次访问。

[Scene 3.
Segmentation]
按理说,现在位于代码段中,VA需要加上CS指定的偏移量才能获得线性地址,不过Windows和Linux都采用Flat Model屏蔽了段机制,毕竟32位地址线足够指向整个4G空间。
所以,逻辑地址(或者说虚拟地址)即是线性地址。
为了实现Flat Model(地址平面化),只需要设置CS、DS两个段寄存器(指向GDT中的段描述符)相应的段描述符,将其基址设为0,段范围限制设为4G。

[Scene 4. Paging]
这里考虑的是页面大小为4KB的情况。
如果没有开启PAE,页式映射过程如下(参考Intel Software Developer Manual):

[ 图 - 3 ]
如果开启了PAE,页式映射过程如下:

[ 图 - 4 ]

[Scene 5. Cache]
昂贵的Cache本身就已经是为了尽量提高CPU的执行速度,消除CPU和内存之间的瓶颈,除此之外,芯片设计者为了提高查找缓存的速度,还将访问Cache和页式映射两件事设计成同时进行的——这利用了低位/页内地址在影射过程的不变形。
先了解下Cache的工作原理。
首先,Cache对于CPU给的地址有两种观察方式:Look-aside和Look-through。在前者模式下,Cache就是作为旁观者,类似抓了一个包过来观察的同时不影响原有的电路逻辑,直到HIT了才终止到内存寻找的逻辑;在后者模式下,Cache就作为必经之路,一定要先Cache判断为MISS后,才允许电路继续执行。
其次,Cache是由若干个Cache-line组成的,每一个Cache-line又分为Tag和Data,一列Cache-line称为一路(1-way)。
用Everest查看本机数据,得知L1-iCache为32KB:

这里引用下Gustavo Duarte博客关于Cache的用图,刚好和我机子上的芯片是一样的:

从上图可以了解到L1 Cache有8路,每一路有64个Cache-line,每一个Cache-line分为24位的tag和64字节的数据部分。
这里可以发现每一路都是4K,对应着一个内存页面,于是可以产生一种良好(当然还有混乱的、只适合小缓存使用的全相联等方式,这里不讨论)的关联方式,每一个内存页相应的页内地址直接对应一个Cache-line。
根据页式映射[ 图 - 3 ]可以知道低12位是不变的,只在最后定位页内地址时才使用到。所以,在进行页式映射的同时,就可以利用地址的低位信息先确定缓存索引,等物理映射完成后,就不必再匹配索引了,直接利用高24位匹配Cache-line的tag。
如果上述tag和索引都匹配到了,那么地址的低6位就可以用来确定Cache-line中64字节的位置,进而获取数据。

[Scene 6. Memory]
如果Cache那边MISS了,就进一步来到了内存。
这时候由控制总线确定操作类型(比如读或写),然后由地址总线确定内存中的位置,再由数据总线来传输要读或者写的数据。
这些电平的传输就要靠我们拆开机箱、卸下风扇才能看到的芯片引脚了。

如果缺页了,就要进行换页了,由OS来控制。

[End]
结尾有点仓促,不过今天确实有点累(昨天去上海听演唱会,回来又熬夜写了下记录),也想这周一定要结束这一个系列的回顾学习,并以此篇作为一个学习小结,毕竟拖了有段时间了。

[参考资料]
1. Wikipedia
2. Gustavo Duarte
3. CSAPP
4. Linux内源源代码情景分析
5. Windows内核原理与实现
6. Intel Software Developer Manual


分享到:
评论

相关推荐

    scratch2源码小老鼠的旅程

    scratch2源码小老鼠的旅程提取方式是百度网盘分享地址

    C++ 旅程

    位域(Bit Fields),也被称为位段,是C/C++中的一种特殊的数据结构,它允许在一个整数类型(通常是`unsigned int`)中定义一系列具有固定宽度的字段,每个字段占据一个或多个位。这种特性非常适用于硬件接口编程和...

    Developer-Starter:只是一些简单的事情,让我开始成为一名开发人员的旅程

    【标题】"Developer-Starter:只是一些简单的事情,让我开始成为一名开发人员的旅程" 提示我们这是一个关于初学者入门编程的资源集合,特别强调了HTML作为基础学习的一部分。这通常意味着该压缩包可能包含一系列的...

    journey_journal:一个让旅行者与来自世界各地的朋友和家人分享旅程的平台

    一个即将推出的平台,供旅行者与来自世界各地的朋友和家人分享他们的旅程。 这个项目最初是在 2012 年夏天我在北欧和中欧旅行时设想的。 1.0 版的预计发布日期:12 月 15 日。 奇科州立大学奇科 CSCI 490 - 高级...

    我的旅程响应式网页模板

    【标题】"我的旅程响应式网页模板"是一个专为展示个人旅行经历或旅游服务设计的网页模板。响应式设计是其核心特点,意味着这个模板能够根据用户设备的屏幕大小自动调整布局,提供良好的视觉体验,无论是桌面电脑、...

    一个报文的路由器之旅(V1.0)

    标题“一个报文的路由器之旅(V1.0)”揭示了我们即将探讨的主题——网络数据包在路由器中的处理和传输过程。这个过程包含了多个层面的技术,包括第二层(L2)和第三层(L3)的协议操作,以及服务质量(QoS)等关键...

    IP基础知识全家桶735 - 782

    计算每类地址的最大主机数时,需要减去全零(网络地址)和全一(广播地址)这两种特殊地址,这是为了确保每个网络至少有一个有效的主机地址。 IP地址的分配和管理随着互联网的发展,逐渐变得紧张。为解决这个问题,...

    user-journal-map-template:用户旅程地图使用模板

    模板提供的 Demo 地址是用户查看和测试模板实际效果的入口,它可能包含了一个预设的示例旅程地图,供用户参考和学习。而 License 指的是 Arvin Xu 对该模板的版权信息,":registered:" 表明该模板可能遵循特定的开源...

    一个月挑战C++(实例讲解)

    在一个月的挑战中深入学习C++,这是一段激动人心的旅程。C++是一种强大的、通用的编程语言,以其高效性、灵活性和面向对象的特性而闻名。它不仅适用于系统编程,还可以用于游戏开发、软件工程等多个领域。在这个实例...

    C_C++指针经验总结.rar

    例如,如果有一个`int`变量`num`,声明一个`int* ptr`,那么`ptr`就指向`num`的地址,即`ptr`是一个指向`int`类型数据的指针。理解这一点有助于我们正确地访问和修改指针所指向的值。 接下来,我们要讨论的是“指针...

    地址请求工具postman for macOsx

    Postman不仅仅是一个简单的请求工具,更是一个全面的API测试套件。你可以为每个请求设置预期的响应状态码、头信息和数据,通过断言检查实际响应是否符合预期。此外,它支持创建测试集合,批量执行一组相关的API请求...

    获取主机IP

    4. **处理结果**:无论使用哪种方法,我们都需要遍历返回的结果,通常只关心第一个IPv4地址(如果需要IPv6,可以选择第一个IPv6地址)。结果可以用`struct in_addr`(对于IPv4)或`struct in6_addr`(对于IPv6)表示...

    MAC-Address-Changer-Timer:此Python 3程序旨在每5秒更改一次系统MAC地址

    Mac地址转换器 此Python程序旨在更改您的系统MAC地址 通过在进入网络之前运行python程序,您将能够使用其他mac地址来...每天您可能都走同样的旅程,并且可能登录到公共或私人网络,该网络节省了您之前几个赛季的访问量

    取易语言类的地址源码-易语言

    在易语言中,创建对象时,系统会自动分配内存并返回一个句柄,这个句柄实际上就是对象在内存中的地址。 下面是一段简单的易语言源码,展示了如何获取类对象的地址: ```易语言 .定义 类 类名 .属性 属性1, 整数型...

    wannago:Python 脚本,用于获取从一个地方到另一个地方的最小路线列表,而无需打开您最喜欢的旅程计划 (TM) 并浪费(至少)60 小时来加载和使用有问题的 GUI(有问题的 JS)

    好吧,你和你的女朋友约会了,你还年轻,而且你生活在一个交通繁忙的首都。 (显然你没有车,它太主流了)。 你想去某个地方,使用公共交通工具。 因此,像往常一样,您使用 Web 浏览器时,您会发现需要执行以下...

    我的第一个HTML代码

    它允许我们将文本、图像、音频、视频等元素组织成...总的来说,"我的第一个HTML代码"是编程旅程的起点,虽然可能简单,但它开启了对网页制作世界的探索。通过不断学习和实践,我们可以创造出功能丰富、设计精美的网页。

    LoginTest:从Rails开始旅程

    在您面前提出的是一个不完整的项目。 请完成以下功能。添加规则模型添加与用户模型关联的新规则模型。 用户应该有很多规则。 规则具有CIDR和权限属性。 CIDR属性应被验证为有效的CIDR范围,权限属性应为“允许”或...

    java 视频教学 下载地址

    - **标题:“java 视频教学 下载地址”**:这个标题表明这是一个提供Java视频教学资源下载的地方。Java是一种广泛使用的编程语言,在软件开发、Web应用、移动应用(尤其是Android应用)等领域有广泛应用。 #### ...

Global site tag (gtag.js) - Google Analytics