问题标签 [memory-segmentation]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
memory - What is segmentation and paging in Computer Science?
I Googled for a long time but I still don't understand how it works as most of the explanation are very technical and there are no illustrations to make it clearer. My primary confusion is that what is its'difference with virtual memory?
I hope this question will have a very good explanation here so that other people who ask the same question can find it here when they Google it.
linux - 内存分段边界检查是如何完成的?
根据关于内存分段的维基百科文章,x86 处理器在硬件中进行分段边界检查。是否有任何系统可以在软件中进行边界检查?如果是这样,这会产生什么样的开销?在硬件实现中,有没有办法跳过边界检查以避免惩罚(如果有惩罚)?
gcc - 如何计算 ELF32 程序头中 p_offset 的值?
我想在 ELF32 二进制文件上应用一些自定义代码转换。首先,我解析 ELF 文件,然后应用转换,然后将 ELF 部分重新组合到一个新的输出文件中。
在我开始实施任何转换之前,我在将 ELF 部分写回新的二进制文件时偶然发现了一个问题,即:当我将这些部分写入新的 ELF 时,我需要正确对齐这些部分。p_align
为此,我尝试使用程序头中的值,但这是不正确的。p_offset
似乎是我在写入 ELF 文件时应该使用的值,但我不知道它是如何计算的。
给你一个例子来说明我的意思。我有以下简单的 C 代码:
我使用 GCC 4.8.2 构建了一个 32 位 ELF 可执行文件。然后我用来readelf -h a.out
打印这个 ELF32 二进制文件的程序头并得到以下输出:
鉴于这个例子,我有以下问题:
如何计算
p_offset
给定段的正确值?当初是怎么p_offset
计算的?为什么第二个 LOAD 段没有与其
p_align
值对齐?具体来说,为什么它开始于0x08049f08
而不是0x08049000
?为什么
p_offset
不小于0xf08
,因为在eh_frame
ELF 文件中它前面的部分以偏移量结束,0x56C
并且文件在此部分和下一个 (init_array
) 开始的部分之间有 2460 个零字节0xf08
?为什么这些部分之间有 2460 个零字节呢?
linux - ubuntu 是否使用“DS”和“SS”段?
在 Ubuntu 14.04 amd64 中,我将 GDT 信息转储到内核模块中:
并转储内核模块的段寄存器:
Q1:内核模块不使用DS和SS吗?
另一方面,我写了一个 ring 3 应用程序,也在 main() 中转储段寄存器:
Q2:应用的CS指向GDT中的64位code desc,SS指向GDT中的DATA desc。没问题,但是为什么app的DS也是00H呢?
我不认为 gcc 可以在不使用 DS 或 SS 的情况下编译所有代码。
dos - x86 分段、DOS、MZ 文件格式和反汇编
我正在拆卸“试驾 III”。这是 1990 年的 DOS 游戏。*.EXE 具有 MZ 格式。我从未处理过分段或 DOS,所以如果您回答我的一些问题,我将不胜感激。
1) 游戏系统要求提到286 CPU,有保护模式。据我所知,DOS 是 90% 的实模式软件,但有些应用程序可以进入保护模式。我可以确定应用程序仅在实模式下使用 CPU 吗?IOW,是否保证段寄存器包含段的实际偏移量而不是段描述符的索引?
2) 所述系统要求提到 1 MB 的 RAM。如果地址空间的最高 384 KB 是为 MMIO 和 ROM 之类的东西保留的,那么如何访问这么多的 RAM?我听说过 UMB(使用 UMA 中的孔来访问 RAM)和 HMA,但它仍然不允许访问整个 1 MB 的物理 RAM。那么,宝贵的 RAM 是不是因为它的物理地址恰好是为 UMA 保留的而浪费了呢?或者也许游戏使用了一些像 LIM EMS 或 XMS 这样的拐杖?
3) 当代码跨越段边界时,CS 会自动递增吗?比如说,IP 达到 0xFFFF,然后呢?CS 是否在执行下一条指令之前切换到下一段?SS也一样。当 SP 一直下降到 0x0000 时会发生什么?
4) 可执行文件的 MZ 标头如下所示:
为什么没有搬迁信息?它甚至意味着如何在没有地址修复的情况下运行?还是将其构建为由程序计数器相关指令组成的完全与位置无关的代码?该游戏带有一个作弊实用程序,它也是一个 MZ 可执行文件。尽管要小得多(8448 字节 - 小到可以放在一个段中),但它仍然具有重定位信息:
这允许 IDA 正确反汇编作弊代码。但是游戏EXE什么都没有,尽管它显然有很多远指针。
5) DOS 中是否有“部分”之类的东西?我的意思是,数据部分,代码(文本)部分等?MZ 头指向堆栈部分,但它没有关于数据部分的信息。数据和代码在 DOS 程序中完全混合了吗?
6) 为什么在 EXE 文件中甚至有一个堆栈部分?它只有零。为什么要浪费磁盘空间而不是仅仅说“从这里开始堆栈”?就像用 BSS 部分完成的一样?
7) MZ头包含关于SS和CS初始值的信息。DS呢?它的初始值是多少?
8) MZ 可执行文件在 exe 数据之后有什么?作弊实用程序在可执行文件的末尾有整个 3507 个字节,看起来像
这是某种调试符号信息吗?
预先感谢您的帮助。
arrays - (C++11) 初始化列表的静态数组和动态数组有什么区别?
例如,有一个包含数千个元素的 int 数组:
和
以上两种方式有什么区别,特别是大括号中的内存使用值?
我知道 st_indices 将在内存中存在,直到程序结束(堆栈),而 dy_indices 将在delete []
(HEAP)之后释放。或者这是关于堆栈与 .DATA 段的问题?
c++ - 我需要破解 C++ 编译器来发出并将特定类指针解释为全局数组中的索引
我有一个特定的类,它仅作为全局数组的元素分配(想象一下文件句柄的示例)。
我需要破解一个 C++ 编译器(例如 g++ 或 clang),以强制该类发出和解释指针,而不是作为该数组内的索引的地址。
所以这意味着我需要类的方法来接受索引作为“this”指针和构造函数来返回数组内的索引而不是指针。
因为我使用的是 x86 架构,所以当类的大小为 1 2 4 或 8 字节时,将这种索引转换为“有效地址”只是寻址模式的问题。
为了管理某种“外部指针”或类似的东西,这种可能性可能已经存在。
我发现知道的是 CLANG 内部的功能如下所述:
使用地址空间#256 对指针进行注释会导致它是相对于 X86 GS 段寄存器生成的代码,而地址空间#257 会导致它相对于 X86 FS 段。请注意,这是一个非常非常低级的功能,只有在您知道自己在做什么时才应该使用(例如在 OS 内核中)。
这是一个例子:
https://clang.llvm.org/docs/LanguageExtensions.html#memory-references-to-specified-segments
这可以解决相对性问题,但不能解决索引乘以到达地址。但是无论如何都不清楚如何使用它来从对象构造函数中获取相对地址。
这个问题由于不够清楚而被搁置,但无论如何我已经使用最终简单的方法解决了它,这里是解决方案的草稿(我最后到达),以帮助理解同样的问题也是一个可能的解决方案。
一个如此复杂的问题可以用足够“简单”的方法来解决,这似乎很奇怪。这正是我需要的解决方案,因为我可以将索引用作对象。
operating-system - x86 上的堆栈和数据段可以重叠吗?
我知道一般来说 x86 中的数据段可以重叠,但堆栈和数据段是否可以重叠我问这个原因通常它们在数据段的说明中彼此相距很远
operating-system - 分段如何比分页更安全?
我在阅读 Galvin 的内存管理时出现了这个问题?有两个部分我不明白。
看第一个是高尔文的直接问题。
我不明白的答案是
“由于分段是基于内存的逻辑划分而不是物理划分,因此任何大小的段只能与每个用户的段表中的一个条目共享。分页必须有一个共享的每个页面的页表中的公共条目”
1)为什么在分段中共享可重入代码更容易?
2)分段比分页更安全吗?为什么
assembly - 使用段寄存器(今天)有什么好处?
我尝试了很长时间来了解段寄存器的用途是什么?我都知道这来自过去(8086),那里只有 1 MB 的物理内存。但是 CPU 只有 16 位宽的地址寄存器。使用这 16 个地址位,您只能寻址 64K 字节。因此,必须将 1MByte 地址空间分成每个 64K 大小的段。
在我看来,这似乎是过去的要求,那些工程师不愿解决某种有限的内存空间等问题。但我的问题是今天的段寄存器有什么优势?您将如何或在哪里以有用的方式使用它们?如果您需要澄清,请发表评论。