如何将全局寄存器变量与%gs(或%fs)相关联?

时间:2016-02-02 22:02:55

标签: c gcc assembly x86-64

在x86_64上,我正在玩一个不支持多线程的玩具操作系统。

我尝试将两个global register variables与%gs和%fs相关联,这样:

<ComboBox Height="33" HorizontalAlignment="Left" Margin="128,107,0,0" Name="comboBox1" VerticalAlignment="Top" Width="245">
            <ComboBox.Resources>
                <Style TargetType="ComboBoxItem">
                    <EventSetter Event="GotFocus" Handler="GotFocusHandler" />
                    <EventSetter Event="LostFocus" Handler="LostFocusHandler" />
                </Style>
            </ComboBox.Resources>
            <ComboBoxItem Content="Cat 1" />
            <ComboBoxItem Content="Cat 2" />
            <ComboBoxItem Content="Cat 3" />
            <ComboBoxItem Content="Cat 4" />
        </ComboBox>

private void GotFocusHandler(object sender, RoutedEventArgs e)
        {
             string HighlightedText = (sender as ComboBoxItem).Content.ToString(); 
             //do some thing
        }

        private void LostFocusHandler(object sender, RoutedEventArgs e)
        {
            string HighlightedText = (sender as ComboBoxItem).Content.ToString();
            //do some thing
        }

但是GCC抱怨“gs”和“fs”不是有效的注册名称。

我尝试了其他寄存器(例如r12和r15)并进行了编译。 我尝试使用%gs和%fs,编译错误仍然存​​在。

是否可以这种方式使用这些寄存器?
而且在amd64中I've read about issues with these registers,但是我无法理解那里指出的问题:它是一个GCC错误还是在amd64中使用寄存器变量的问题?

1 个答案:

答案 0 :(得分:5)

80386兼容CPU有六个段寄存器,命名为cs,ds,ss,es,fs和gs。这些段寄存器用于称为分段的功能,并且基本上充当指向段描述符表的指针,其地址计算中隐含地添加了指针。†< / SUP>

这些段寄存器无法实际用于保存任意数据,因为除了某些特定方式(les和朋友)将值加载到它们之外,当加载无效值时会导致异常。它们用于以下目的:

  • 在获取指令时使用段寄存器cs,在获取数据时使用ds,在从堆栈获取数据时使用ss(即相对于esp或ebp),并且es与某些指令(如scasb)结合使用。在几乎每个带有内存操作数的指令中,您都可以覆盖解析地址的段。
  • 更改cs用于在操作系统之间在实模式,16位保护模式,32位保护模式和长模式之间切换。在Windows上,这也可以由应用程序完成(但不建议这样做)。通过远程跳转或呼叫来改变cs。
  • OpenBSD通过在cs上设置长度限制来实现执行防止方案(W ^ X),这样就不会同时写入和执行任何数据。
  • 默认情况下,fs和gs段从不使用,通常用于实现thread-local storage。您可以使用Linux上的arch_prctl系统调用来设置与fs和gs关联的偏移量,但请记住,这样做会破坏libc对于这些段描述符的段描述符表中存储的偏移量的期望并且可能会使errno无法使用基本设施。
  • 在长模式(64位模式)下,整个分段机制不可用。可以使用fs和gs但是它们的值不会在段描述符表中查找,而是有两个特殊寄存器,其中内核存放一个偏移量,只要使用fs和gs就会添加该偏移量。所有其他机制都不可用。

这是一个简化的描述,它实际上有点复杂。