【问题标题】:Equivalent eip/rip, ebp/rpb, UESP/rsp registers for ARM / Aarchh64 processorARM / Aarchh64 处理器的等效 eip/rip、ebp/rpb、UESP/rsp 寄存器
【发布时间】:2021-12-10 16:48:00
【问题描述】:

Heading ##用于 Intel CPU 但用于 ARM/Aaarch64 CPU 的 eiprip 寄存器等效于什么?

我需要翻译为使用 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 寄存器的比较和等效表?

谢谢。

【问题讨论】:

  • 寄存器名为PC,但它不是通用寄存器。请注意,作为独立的体系结构,x86 和 AArch64 寄存器之间并没有真正的 1:1 对应关系。您可以在 x86 寄存器和您想要的 31 个通用寄存器之间使用任何分配,尽管SP 应该保持SP。如果你能告诉我你想做什么,也许我可以提供更直接的帮助。
  • ARM 具有范围有限的 PC 相对寻址模式。我假设 AArch64 也可以,但它也有 adrp 等用于将 PC 相对地址生成到另一个寄存器中,例如 x86-64 RIP 相对 LEA。
  • @fuz :谢谢,我会用电脑试试。它适用于适用于 x86-64 并且需要通过 asm 寄存器访问 cpu 的 Pascal fpc 调试器程序。例如:函数 GetInstructionPointerRegisterValue 使用:regs32[eip] 或 regs64[rip]。 GetStackBasePointerRegisterValue 使用:regs32[ebp] 或 regs64[rbp]。 GetStackPointerRegisterValue 使用:regs32[UESP] 或 regs64[rsp]。
  • @Peter:好的,我也会尝试使用 adrp。稍后再写给你

标签: assembly arm arm64 eip program-counter


【解决方案1】:

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

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

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

【讨论】:

  • 我会一步一步做的。
  • Aaargh,那个输入...所以我说我会一步一步做。现在最需要的是找到 eip/rip 的等价物。我将尝试使用 pc 和 adrp。其他 2 个步骤用于与 ebp/rbp 和 UESP/rsp 等效。如果您有想法:欢迎 ;-)。我希望通过这三种方法,我可以走得更远。非常感谢。
  • @fredvs:PC 相当于 RIP。您真的想要 RIP 的某些 用法 的等价物吗?查看编译器输出,特别是针对非叶函数的优化编译器输出应该做一些推送/弹出等效的东西,比如 AArch64 ldp/stp 具有预减量 ([sp, -32]!) 或后增量寻址模式 ( [sp], 32)。或 ARM stm / ldm。或者要查看它设置帧指针,请使用-fno-omit-frame-pointergodbolt.org/z/sbT7jKa65 或者对于 PC-relative,访问全局变量,可能使用 -fPIE 强制 PC-relative 但不是 GOT。
  • 不,它更简单(但也很复杂)。在 Pascal 程序中,有一些 asm 访问 intel cpu。
  • @fredvs:然后在你的问题中问这个问题,如果你不想了解一般的东西,而不是一般抽象的东西。
【解决方案2】:

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)。这包括movadd 等基本内容,因此您只需执行mov x0, sp 即可获取其当前值。

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


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

【讨论】:

  • 非常感谢 Nate 提供的宝贵信息。嗯,是的,正如我所担心的那样,像“谷歌翻译 x86 到 arm”这样的简单解决方案还不存在。 ;-(。而且我必须更深入地了解 ARM 指令并回到我的汇编课程。无论如何,如果有人知道 x86 与 arm 的“或多或少”可比较的指令图表,我很感兴趣(但是是的,我理解它没有多大意义,因为架构太不同了)。非常感谢。Fred
猜你喜欢
  • 2015-02-10
  • 2021-03-03
  • 2014-01-06
  • 2021-08-17
  • 1970-01-01
  • 2020-05-02
  • 1970-01-01
  • 2012-03-29
  • 2012-01-11
相关资源
最近更新 更多