1

标题##什么是eip的等价物,用于 Intel CPU 但用于 ARM/Aaarch64 CPU 的rip寄存器?

我需要翻译为使用 32 位eip或 64 位rip寄存器的 Intel CPU 编写的应用程序。

这些方法使用英特尔寄存器:

函数 GetInstructionPointerRegisterValue --> 使用:regs32[eip] 或 regs64[rip]。

函数 GetStackBasePointerRegisterValue --> 使用:regs32[ebp] 或 regs64[rbp]

函数 GetStackPointerRegisterValue --> 使用:regs32[UESP] 或 regs64[rsp]。

我应该为 ARM ARM/Aaarch64 使用什么类似的寄存器?

它是否存在 x86/amd64 寄存器与 arm/aarch64 寄存器的比较和等价表?

谢谢。

4

2 回答 2

1

ARM/AArch64 上的程序计数器称为 PC。

ARM 具有范围有限的 PC 相对寻址模式。我假设 AArch64 也可以,但它也具有adrp用于将 PC 相对地址生成到另一个寄存器中的功能,例如 x86-64 RIP 相对 LEA。

ARM 和 AArch64 没有很多/任何指令隐式使用除堆栈指针之外的任何特定通用寄存器,因此 x86-64 的“等价表”会非常短。例如,与 x86 不同shl r/m, cl,您不需要特定寄存器中的值来移动它,更像 x86 BMI2shlx reg, reg/mem, reg但没有 CISC 使用内存源的能力。ARM 和 AArch64 选择了一种更加正交的设计,而不是像 x86 那样对不同的寄存器进行大量隐式使用,以允许使用 x86 的可变长度指令编码实现更短的指令。

于 2021-12-10T17:46:18.323 回答
1

x86 指令指针的 AArch64 等效项是程序计数器寄存器,pc. 与 ARM32 不同,pc它不是通用寄存器,不能与mov. 但是,如果您需要它的“当前值”,即当前指令的地址(或下一条,无论您喜欢哪个),您可以使用adr返回值pc加上立即偏移量的指令来执行此操作。(adrp这里只会得到它的高 52 位。)我认为大多数汇编程序不会让您直接将该偏移量指定为 0,但您可以使用标签来做到这一点:

this_instruction:
    adr x0, this_instruction // x0 <- address of this_instruction

调用 AArch64 堆栈指针sp。它不是一个通用寄存器,但可以像几个特定指令中的一个一样使用(它被编码为寄存器 31,大多数情况下编码零寄存器xzr,但有些指令是特殊情况将其视为sp反而)。这包括基本的东西,比如mov, add,所以你可以做得到mov x0, sp它的当前值。

按照惯例,通用寄存器x29在需要时用作帧指针。mov x0, x29您可以使用或x29直接用作您喜欢的任何指令的输入来检索它。但是,请注意,不调用其他函数的“叶”函数可能不使用帧指针,在这种情况下,x29可能会指向调用函数的堆栈帧。


一般来说,像这样“翻译”x86 代码,一次只查看一条指令并尝试用一个精确的 ARM 等效指令替换它,不太可能成功。机器和/或调用约定的许多方面没有直接的等价物。你真的必须退后一步,弄清楚整个 x86 代码试图做什么,然后考虑如何在 ARM 上产生等效的行为。所以不要在“这段代码正在访问eip,等价物是什么?”的水平上工作。而是“这段代码试图进行系统调用/堆栈展开/上下文切换等;如何在 ARM 上做到这一点?”

于 2021-12-12T18:04:04.180 回答