如何在 x86-64 汇编指令中解释 DS 寄存器?

逆向工程 艾达 拆卸 分割
2021-06-24 15:37:52

IDA 反汇编了一条 x86-64 指令,如下所示:

0000000000000761                 lea     rdx, ds:0[rax*4]

我所知道的是,段寄存器只在分段内存模型中相关,而在分页的情况下,它们在 GDT/LDT 中保存一个索引。为什么上面的指令莫名其妙地指向了ds段寄存器?

1个回答

段仍然在 64 位长模式下使用并且仍然设置,除了 CPU 将它们的基数视为 0(gs 和 fs 除外),并且不执行限制检查。rax 的默认段确实是ds,但这可以通过段覆盖来更改。lea rdx, ds:0[rax*4]is lea rdx, ds:[rax*4 + 0],即lea rdx, ds:[rax*4],与lea rdx, [rax*4]执行该指令时相同ds,默认情况下AGU 使用段描述符rax执行权限检查,但不进行限制或基本检查。这个段描述符要么被重命名并被放置在保留站中(因此解码器和分配器的工作是根据前缀覆盖或缺少前缀使用正确的段描述符)或者是 AGU 内部的,并且 AGU 使用可能对要使用的段进行编码的 uop 操作码。我也看到了lea rdx, [ds:rax]记号,这是同样的事情lea rdx, ds:[rax],但问题是lea rdx, [ds:rax*4]将语义误导,因为在x86你只能做lea rdx, ds:[rax*4]我相信gs:[0x32], gs:0x32并且 [gs:0x32]在 x86 程序集/反汇编中都代表相同的东西,例如gs:0x32并不意味着“获取 ' 的计算线性地址gs:0x32,因为我们有lea,并且gs:[0x32]并不意味着“获取 at 值处的地址,ds:[0x32]然后将其用作 gs 的偏移量并获取计算出的线性地址”,因此其他 2 种形式可以安全地表示[gs:0x32],并且如上所述gs:[...]更清楚,因为它在 a涉及尺度或索引