我有内存布局(在增加内存地址中),如:
代码部分(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生成代码。?
提前致谢!!
答案 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 movs
或rep stos
for memcpy / memset。 memcpy
或memset
的库实现也可能在某些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?。