我对x86程序集中使用冒号有点困惑。我知道在实模式下%gs:0x14
将是%gs
移位4位的地址,并添加0x14
。但在保护模式下它是一样的吗?例如,在保护模式下,
movl %gs:0x14 %eax
访问%gs:0x14
的方式是什么?它就像0x14(%gs)
或与实模式相同?
更新:
为了使我的问题更清楚,假设%gs = 0x1234
在指令movl %gs:0x14 %eax
之后%eax的值是多少。
更多信息:
刚刚发现这个文档对gs和fs在不同系统中的功能很有用 http://www.akkadia.org/drepper/tls.pdf
此链接提供有关segment:offset address。
的信息答案 0 :(得分:1)
您需要仔细阅读架构的application binary interface规范(可能是x86-64
),即X86-64 ABI。
您会发现%gs
与线程本地存储有关。请参阅this answer。
因此,您的机器指令可能正在加载当前TLS的偏移0x14
处的字。
答案 1 :(得分:1)
首先,让我们来处理这些条款。看起来你通常使用“保护模式”,而不是真实模式。但是,至少在英特尔手册中,该术语仅适用于32位模式。对于64位模式,他们使用了一个糟糕的营销术语“IA-32e模式”,这与AMD的“长模式”相比是可怕的,但两者仍然隐藏了64位模式也受到保护的事实。
这种差异很重要,因为对于32位和64位保护模式,处理%gs是不同的。对于32位,它是另一个段寄存器。线程切换代码用相同虚拟空间中当前线程的段基础填充它,因此,与{CS,DS,ES,SS}不同,它在平面模式下不是零。对于64位,它只是保留在处理器MSR中的偏移量,并且还由调度程序更改为当前线程TLS地址。 (Linux / * BSD / Windows /等之间的细节可能有所不同。%fs和%gs用于哪个角色。)但是,作为一个常见的结果,当看到像%gs:0x14这样的访问时你应该意识到
除非你开发内核或其他深层系统的东西,否则你需要知道所有这些。酒。