zoukankan      html  css  js  c++  java
  • Linux内存寻址

    我会尽力以最简洁清晰的思路来写这篇文章。

    所谓内存寻址也就是从写在指令里的地址,转化为实际物理地址的过程。因为操作系统要兼顾许多东西,所以也就变得复杂。

    逻辑地址 → 线性地址 → 物理地址

    逻辑地址 = 段 + 偏移量

    因为:最开始cpu中的alu宽度只有16位,但地址总线宽度有20位。所以设置四个段寄存器:cs(指令),ds(数据),ss(堆栈),es(其它)。

    每个段寄存器16位,对应地址总线高16位。每条指令中的16位内部地址与某个段寄存器中内容相加,得到20位的实际地址。

    上述的16位内部地址到20位实际地址的转换还是8086的时代。

    到了80386,32位cpu的时代,许多情况都发生改变。其中一点:要实施“保护模式”。还要兼容过去的段寄存器。

    于是,之前的公式从新写为:

                 逻辑地址 = 段选择符(16位) + 偏移量(32位)

    所以对80386cpu的寻址还是要基于从前8086寻址方式来理解,《linux内核源代码情景分析》中这样描述:

    可简单记为:段寄存器(段选择符) → 地址段描述结构(段描述符) → 基地址 → 指令中发出的地址 + 基地址 = 物理地址

    地址段描述结构(段描述符) 从何而来:在cpu中增设两个寄存器,一个是全局性的段描述表寄存器GDTR;一个是局部性的段描述表寄存器LDTR。

                          段描述符地址  =  段选择符index字段×8 + gdtr/ldtr寄存器中的值

    这张图可以表现,怎样由段寄存器(段选择符)得到段描述符 。

    段选择符得到“段”的过程,一种是访问段描述表得到段描述符。

    另外还可以通过非编程寄存器,不访问段描述表得到段描述符。

    总之,是段选择符(段寄存器) → ( 段描述符表 → )段描述符 → 基地址的过程。

    段描述符:

    继续推导之前的式子:

                段描述符的获得:段选择符index字段×8 + gdtr/ldtr寄存器中的值

                基址 = 段描述符Base字段

                逻辑地址 = 段选择符(16位) + 偏移量(32位) = 段描述符Base字段 + 偏移量

    参考资料:

       《汇编语言》王爽

       《linux内核源代码情景分析》毛德操

       《Understanding the Linux Kernel》Daniel P. Bovet / Marco Cesati 

  • 相关阅读:
    C语言 sprintf 函数 C语言零基础入门教程
    C语言 printf 函数 C语言零基础入门教程
    C语言 文件读写 fgets 函数 C语言零基础入门教程
    C语言 文件读写 fputs 函数 C语言零基础入门教程
    C语言 fprintf 函数 C语言零基础入门教程
    C语言 文件读写 fgetc 函数 C语言零基础入门教程
    C语言 文件读写 fputc 函数 C语言零基础入门教程
    C语言 strlen 函数 C语言零基础入门教程
    Brad Abrams关于Naming Conventions的演讲中涉及到的生词集解
    适配器模式
  • 原文地址:https://www.cnblogs.com/rixiang/p/5049312.html
Copyright © 2011-2022 走看看