什么是GCC编译器选项以获取x86中的Segment Override前缀

时间:2013-02-26 12:00:36

标签: gcc compiler-construction linker x86

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

代码部分(0-4k),数据部分(4k-8k),堆栈部分(8k-12k),CustomData部分(12k-16k)。

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

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

因此,对于所有操作,数据部分(4k-8k)将默认具有#DS。除了某些可以使用ES的strop。像:

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

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

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

所以我的问题是:

GCC是否有任何x86编译器标志,可用于告诉编译器使用#ES进行CustomData段代码访问。?

表示编译器标志,它将使用#ES为CustomData Section生成代码。?

提前致谢!!

2 个答案:

答案 0 :(得分:0)

尽管问题是要求让gcc的代码生成使用es前缀访问自定义部分的选项,但是如果您想使用手写代码进行编写,则AT&T语法已经允许例如%es:(%eax)。

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

(根据Peter Cordes的有用评论,使此评论社区Wiki。)

答案 1 :(得分:0)

引用clang language-extension docs

中的示例
#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 movsrep stos for memcpy / memset。 memcpymemset的库实现也可能在某些CPU上使用复制/移动。相关:Why is std::fill(0) slower than std::fill(1)?

很明显,这确实是底层的东西,并且只有在您已经设置GS或FS基址的情况下才有意义。 (wrfsbase)。请注意,i386 Linux使用gs进行用户空间中的线程本地存储,而x86-64 Linux使用fs


我不知道gcc,ICC或MSVC这样的扩展名。

好吧,GNU C中有__thread,它会根据目标平台使用%gs:%fs:前缀。 How does the gcc `__thread` work?