Home > front end >  Equivalent eip/rip, ebp/rpb, UESP/rsp registers for ARM / Aarchh64 processor
Equivalent eip/rip, ebp/rpb, UESP/rsp registers for ARM / Aarchh64 processor

Time:12-13

Heading ##What is the equivalent of eip, rip registers used for Intel CPU but for ARM/Aaarch64 CPU ?

I need to translate a application written for Intel CPU that uses the 32 bit eip or the 64 bit rip register.

Thoses methods use intel registers:

function GetInstructionPointerRegisterValue --> uses: regs32[eip] or regs64[rip].

function GetStackBasePointerRegisterValue --> uses: regs32[ebp] or regs64[rbp]

function GetStackPointerRegisterValue --> uses: regs32[UESP] or regs64[rsp].

What similar register should I use for ARM ARM/Aaarch64 ?

And does it exist a table with comparison and equivalence of the x86/amd64 registers vs the registers of arm/aarch64 ?

Thanks.

CodePudding user response:

The program counter on ARM/AArch64 is called PC.

ARM has a PC-relative addressing mode with limited range. I assume AArch64 does, too, but it also has adrp and so on for generating PC-relative addresses into another register, like x86-64 RIP-relative LEA.

ARM and AArch64 don't have many/any instructions that implicitly use any specific general-purpose register other than the stack pointer, so the "equivalence table" with x86-64 would be very short. Unlike x86 shl r/m, cl for example, you don't need a value in a specific register to shift by it, more like x86 BMI2 shlx reg, reg/mem, reg but without the CISC ability to use a memory source. ARM and AArch64 picked a more orthogonal design to start with instead of having lots of implicit uses for different registers like x86 did to allow shorter instructions with x86's variable-length instruction encoding.

CodePudding user response:

The AArch64 equivalent of the x86 instruction pointer is the program counter register, pc. Unlike on ARM32, pc is not a general-purpose register and cannot be used with ordinary instructions like mov. However, if you need its "current value", i.e. the address of the current instruction (or the next one, whichever you prefer), you can do this with the adr instruction, which returns the value of pc plus an immediate offset. (adrp here would only get you the high 52 bits of it.) I don't think most assemblers will let you specify that offset as 0 directly, but you can do it with a label:

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

The AArch64 stack pointer is called sp. It is not quite a general-purpose register, but can be used like one in a few specific instructions (it is encoded as register 31, which most of the time encodes the zero register xzr, but some instructions are special-cased to treat it as sp instead). This includes basic things like mov, add, and so you can just do mov x0, sp to get its current value.

The general-purpose register x29 is by convention used as a frame pointer when one is needed. You can retrieve it with mov x0, x29 or just use x29 directly as input to any instruction you like. However, note that "leaf" functions that don't call other functions may not use the frame pointer, in which case x29 likely points instead to the calling function's stack frame.


In general, "translating" x86 code like this, by just looking at one instruction at a time and trying to replace it with an exact ARM equivalent, is unlikely to succeed. Many aspects of the machines and/or calling conventions don't have direct equivalents. You really have to step back, figure out what the x86 code as a whole is trying to do, then think about how to produce equivalent behavior on ARM. So don't work on the level of "this code is accessing eip, what's the equivalent?". But rather "this code is trying to do a system call / stack unwind / context switch, etc; how does one do that on ARM?"

  • Related