分段寄存器使用【JAVA教程】

!
也想出现在这里? 联系我们
信息

分段寄存器使用,第1张

概述分段寄存器使用

我想了解内存pipe理是如何进行低级别的,并有几个问题。

1)由Kip R. Irvine撰写的一本关于汇编语言的书说,在实模式中,当程序启动时,首先在三个段寄存器中加载代码,数据和堆栈段的基地址。 这对我来说有点模糊。 这些值是手动指定还是汇编器生成指令将值写入寄存器? 如果它自动发生,如何找出这些细分的大小?

2)我知道linux使用扁平线性模型,即以非常有限的方式使用分割。 另外,根据DanIEl P. Bovet和marco Cesati的“了解linux内核”,GDT中有四个主要部分:用户数据,用户代码,内核数据和内核代码。 所有四个段都具有相同的大小和基地址。 我不明白为什么只有在types和访问权限(他们都产生相同的线性地址,对不对?)有四个需要。 为什么不使用其中的一个,并将其描述符写入所有段寄存器?

3)不使用分段的 *** 作系统如何将程序划分为逻辑分段? 例如,他们如何区分堆栈和没有段描述符的代码。 我读过分页可以用来处理这样的事情,但不知道如何。

CUDA内存错误

Python脚本将结果导入到ctrl-c内存

双socketsvs单sockets内存模型?

为什么在linux上使用更multithreading时内存消耗会增长? (C ++)

分段错误无效内存0x0

运行NDSolve时内存耗尽

虚拟内存中NUMA如何表示?

有关linux内存types的问题

mmap或malloc分配RAM吗?

如果共享内存的进程中有一个被杀死,共享内存会发生什么变化?

Benoit对问题3的回答扩大了…

程序分为逻辑部分,如代码,常量数据,可修改的数据和堆栈由不同的代理在不同的时间点完成。

首先,你的编译器(和链接器)在指定这个分区的地方创建可执行文件。 如果您查看许多可执行文件格式(PE,ELF等),您会看到它们支持某种类型的段或段,或者您想要调用的任何类型的段。 除了文件中的地址,大小和位置外,这些部分还具有属性,告诉 *** 作系统这些部分的用途,例如本节包含代码(这里是入口点),初始化的常量数据 – 未初始化的数据文件中的空间),这里是关于堆栈的东西,在那里是依赖关系列表(例如,DLL)等等。

接下来,当 *** 作系统开始执行程序时,它解析该文件以查看程序需要多少内存,每个部分需要何处以及需要什么内存保护。 后者通常通过页表完成。 代码页被标记为可执行和只读,常量数据页被标记为不可执行和只读,其他数据页(包括堆栈)被标记为不可执行和读写。 这是应该如何正常的。

通常,程序需要读写,同时需要动态生成代码的可执行区域,或者只能修改现有的代码。 组合的RWX访问既可以在可执行文件中指定,也可以在运行时请求。

可以有其他特殊页面,例如用于动态堆栈扩展的保护页面,它们被放置在堆栈页面旁边。 例如,程序开始时为64KB的堆栈分配了足够多的页面,然后当程序尝试访问超出这一点时, *** 作系统拦截访问这些防护页面,为堆栈分配更多的页面(最大支持的大小)和进一步移动守卫页面。 这些页面不需要在可执行文件中指定, *** 作系统可以自行处理它们。 该文件应该只指定堆栈的大小和位置。

如果 *** 作系统中没有硬件或代码来区分代码存储器和数据存储器,或者强制执行存储器访问权限,则该部门是非常正式的。 16位实模式DOS程序(COM和EXE)没有以某种特殊方式标记的代码,数据和堆栈段。 COM程序拥有一个普通的64KB段,它们以IP = 0x100和SP = 0xFFxx开始,代码和数据的顺序可以是任意的,它们可以实际上交织在一起。 DOS EXE文件只指定了起始CS:IP和SS:SP位置,而且代码,数据和堆栈段与DOS无法区分。 所有需要做的就是加载文件,执行重定位(仅适用于EXE),设置PSP(程序段前缀,包含命令行参数和一些其他控制信息),加载SS:SP和CS:IP。 它不能保护内存,因为内存保护在实地址模式下不可用,所以16位DOS可执行格式非常简单。

你必须阅读一些真正的旧书,因为没有人编程的实模式了;-)在实模式中 ,你可以得到一个物理地址的内存访问与phyical address = segment register * 0x10 + offset ,偏移量是一个值在一个通用寄存器内。 因为这些寄存器的宽度是16位的,所以一个段的长度将是64kb,对于它的大小没有什么可做的,只是因为没有属性! 使用* 0x10乘法,1mb的内存变得可用,但是有重叠的组合,这取决于你放入段寄存器和地址寄存器的内容 。 我没有编译任何实模式的代码,但是我认为在二进制加载过程中需要设置段寄存器 ,就像加载器在加载ELF二进制文件时分配一些页面一样。 但是我已经编译了裸机内核代码,我必须自己设置这些寄存器。

由于架构的限制,平面模型中有四个部分是强制性的。 在保护模式下 , 段寄存器不再包含段基地址,而是基本上是GDT偏移量的段选择器 。 根据段选择器的值,cpu将处于特定的权限级别,即CPL(Current Privilege Level,当前权限级别)。 段选择器指向具有dpl(描述符权限级别)的段描述符,如果段寄存器被该选择器填充(对于代码段选择器至少为真),则最终为CPL。 因此,您至少需要一对段选择器来区分内核和用户空间。 而且,段既可以是代码段,也可以是数据段,因此您最终会在GDT中使用四个段描述符 。

我没有任何严重的 *** 作系统的例子,使用任何分割,只是因为分割依然存在的落后顺从。 使用平面模型的方法不过是摆脱它的意思。 无论如何,你说得对,分页的方式更加高效和多功能,几乎所有的体系结构(至少有这些概念)都可以使用。 我无法在这里解释分页的内部信息,但是您需要知道的所有信息都在英特尔的优秀人员中: 英特尔®64和IA-32架构软件开发人员手册卷3A:系统编程指南,第1部分

在这种情况下维基百科是你的朋友。 http://en.wikipedia.org/wiki/Memory_segmentation和http://en.wikipedia.org/wiki/X86_memory_segmentation应该是很好的起点。

不过,我相信这里有其他人可以亲自提供深入的解释。

总结

以上是内存溢出为你收集整理的分段寄存器使用全部内容,希望文章能够帮你解决分段寄存器使用所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

© 版权声明
THE END
喜欢就支持一下吧
点赞97 分享
评论 抢沙发

请登录后发表评论

    请登录后查看评论内容