【问题标题】:What registers are considered "address registers" in Assembly?哪些寄存器在汇编中被视为“地址寄存器”?
【发布时间】:2020-12-09 23:28:46
【问题描述】:

哪些寄存器被认为是汇编中的“地址寄存器”?我认为答案类似于:所有段寄存器,加上EBPESPEIP,因为它们包含“地址”,如果我可以这么说的话。但令我惊讶的是,正确的答案实际上是:段寄存器和EIP。我找不到任何类型的解释,很难。为什么段寄存器和EIP被称为“地址寄存器”?为什么这些寄存器专门而不是其他一些寄存器? (P.S. 如果有任何区别,我使用的是 x86 NASM)

【问题讨论】:

  • 一些架构(如 M68k)有专用的地址寄存器。 X86 只有通用寄存器,虽然在 16 位模式下,只有 bxsidibp 可用于显式内存操作数(sp 用于一堆隐式内存操作数)。然而,“地址寄存器”这个词并不常用来描述 x86 上的任何东西。段寄存器ebpespeip是“地址寄存器”的说法从何而来?
  • 这只是一个定义问题。无论如何,我认为没有人考虑段寄存器地址寄存器。 EIP 甚至不是可直接访问的寄存器,但它被 cpu 用作地址。类似地,某些指令隐式使用ESPESIEDIEBP 作为地址,但您可以显式使用其中任何一个和其余 GPR,例如[EAX].
  • “地址寄存器”没有适用于 ISA 的特定技术含义。没有广泛同意的规则可以使这种分类选择正确但其他分类不正确。 m68k 意义上的“地址寄存器”意味着它主要用于保存指针,但您不能将程序计数器用作数据指针。 (而且 32 位 x86 甚至没有 RIP 相对寻址。)因此,在这里进行分类的人使用了不同的解释。
  • 寄存器显然不是普通的地址寄存器。在保护模式下,他们选择一个 GDT 条目。不过,内部/隐藏段 base 拥有一个实际的线性地址。 (对于 FS 和 GS,可通过 wrmsrMSR_FS_BASE / MSR_GS_BASE 访问。对于其他人,只能通过修改选择器来触发加载新描述符。)
  • 基本上我不认为这是一个非常有用的概念,如果你这样做的话。一个有趣的问题是您可以在寄存器中保留多少数据指针,以便可以使用其中的任何一个,例如您可以一次循环多少个数组而不会用完寄存器。 “m68k 有多少个地址寄存器?包括堆栈指针在内的 8 个”。但这对于将 x86 与其他 ISA 进行比较并不是一个有用的定义。特别是考虑到 x86 几乎普遍与 ss.base = cs.base = ds.base = es.base 平面内存模型一起使用。

标签: assembly x86 cpu-architecture terminology cpu-registers


【解决方案1】:

对于80x86,“地址寄存器”没有明确权威的定义;并且(除非有明确和权威的定义 - 例如在 CPU 制造商的手册中)“地址寄存器”可以定义为您喜欢的任何内容。

例如,对于 80x86,您可以说所有通用寄存器都可以用作地址(例如“mov eax,[eax]”或“mov eax,[ebx]”或..),因此所有通用寄存器都是“地址注册”。

再举一个例子,对于 80x86,你可以说段寄存器包含一个东西结构(可见值、基地址、限制、类型),因此不是“地址寄存器”,几乎所有普通寄存器(EIP , ESP, ESI, EDI, ...) 只能包含段内的偏移量(其本身不是地址),因此也不是“地址寄存器”;而且根本没有地址寄存器。

【讨论】:

  • 在 x86-64 中,段基数固定为 0,因此更容易争辩说 GP 整数 reg 在这个意义上是“地址寄存器”:线性地址 = 偏移量,除非您覆盖到 FS或 GS 基地。但是,是的,受保护模式和真实模式的有趣之处。
  • @PeterCordes:再举一个例子,对于 80x86 中的 64 位代码,您可以说存在“虚拟地址寄存器”(GDTR、IDTR、riprsp)和一些“物理地址寄存器”(cr3,本地 APIC 基地址 MSR),但没有“地址寄存器”,因为当有 2 个(或更多)不同类型的地址时,这没有意义。 ;-)
  • 正如他们所说,计算中只有两个难题:命名和缓存失效。根据该论点,如果系统具有 MMU,m68k 的地址寄存器将成为“虚拟地址寄存器”。 (虽然这略有不同,因为 MMU 对于 m68k 是可选的,但 x86-64 长模式需要启用分页。)
  • 另外应该提到的是AVX引入了VSIB寻址,其中XMM0..ZMM31在聚集/分散指令中起到索引寻址寄存器的作用,比如felixcloutier.com/x86/vgatherdpd:vgatherqpd跨度>
【解决方案2】:

毫无疑问,一个或一些指令集要解决某些问题,您必须使用一个特定的寄存器或一组寄存器。但这是例外而非规则。

对于有问题的指令集,只需查找文档并查找可以寻址内存并查看编码的加载/存储/读取/写入/移动/等指令,并将显示该寄存器的列表可用于保存地址事务的地址的架构(或者有时立即数可能在指令本身中,即地址而不是在寄存器中)。

对于 x86 将反对某些 cmets 并说段寄存器特别是地址寄存器,因为它们的内容专门用于生成地址。不是靠它自己,而是与其他位组合来创建完整地址。但是它们的目的和内容用于地址生成。不过,我当然不会单独使用术语地址寄存器来描述它们。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-03-25
    • 1970-01-01
    • 1970-01-01
    • 2016-11-11
    • 1970-01-01
    • 2013-01-10
    • 1970-01-01
    • 2012-01-19
    相关资源
    最近更新 更多