0

我有内存布局(在增加内存地址中),例如:

代码段 (0-4k)、数据段(4k-8k)、堆栈段(8k-12k)、自定义数据段(12k-16k)。

我在自定义数据部分放置了一些特殊的数组和结构。

据我所知,数据段 (#DS)Selector 将用于任何与数据相关的编译器代码。

所以数据部分(4k-8k)默认情况下所有操作都有#DS。除了一些可以使用 ES 的 str op。喜欢:

mov    $0xc00,%eax
addl   $0xd, (%eax)

但是,我想使用 Extra Segment(#ES) 选择器进行 CustomData 访问。我将为具有不同 Base 和 Limit 的 ES 定义一个新的 GDT 条目。喜欢:

mov    $0x3400,%eax
addl   $0xd, %es:(%eax)

所以我的问题是:

GCC 是否有任何 x86 编译器标志,可用于告诉编译器使用 #ES 进行自定义数据部分代码访问。?

意思是,编译器标志将使用 #ES 为 CustomData 部分生成代码。?

提前致谢 !!

4

2 回答 2

0

虽然问题是要求选择让 gcc 的代码生成使用 es 前缀来访问自定义部分,但如果您想在手写代码中执行此操作,AT&T 语法已经允许例如 %es:(%eax)。

注意,这可能会破坏 gcc 有时内联的 rep-string 指令;fs 或 gs 将是唯一明智的选择,即使在 x86-64 中仍然可用。

(根据 Peter Cordes 的有用评论制作此评论社区 wiki。)

于 2018-08-02T02:09:48.013 回答
0

引用clang 语言扩展文档中的示例

#define GS_RELATIVE __attribute__((address_space(256)))
int foo(int GS_RELATIVE *P) {
  return *P;
}

编译为(在 X86-32 上):

_foo:
        movl    4(%esp), %eax         # load the arg
        movl    %gs:(%eax), %eax      # use it with its prefix
        ret

地址空间 256 是gs, 257 是fs, 258 是ss

文档没有提到es;编译器通常假设es= ,因此如果他们根据调整选项选择这样做,ds他们可以自由地内联rep movs或用于 memcpy / memset。rep stos某些 CPU 上的库实现memcpymemset也可能使用 rep stos/movs。相关:为什么 std::fill(0) 比 std::fill(1) 慢?

显然,这确实是低级的东西,只有在您已经设置了 GS 或 FS 基地址时才有意义。( wrfsbase)。请注意 i386 Linuxgs用于用户空间中的线程本地存储,而 x86-64 Linux 使用fs.


我不知道像 gcc、ICC 或 MSVC 这样的扩展。

嗯,__thread在 GNU C 中有,它将根据目标平台使用%gs:%fs:前缀。 gcc `__thread` 是如何工作的?.

于 2018-08-18T04:14:55.697 回答