Make a subroutine that looks somewhat like:
.text
.globl GetIP
GetIP:
move $v0, $ra
jr $ra
And then call the routine; it'll give you the address of the first instruction after the call.
Domanda
I'd like to do backtrace on MIPS. Then, I face one problem: how do I get the current PC register value, since it doesn't belong to 32 normal registers.. Thanks for your suggestion..
Soluzione
Make a subroutine that looks somewhat like:
.text
.globl GetIP
GetIP:
move $v0, $ra
jr $ra
And then call the routine; it'll give you the address of the first instruction after the call.
Altri suggerimenti
after a jal call it will be copied to the ra register... so you could store ra, then jal to the next line, read ra, restore ra.
Although this question isn't tagged c
, I figured it might be useful to share a solution utilizing inline assembly in gcc
.
__attribute__((noinline)) static void *get_pc(void)
{
void *pc;
asm volatile ("move %0, $ra" : "=r"(pc));
return pc;
}
Of course, the gist of the solution is the same as the currently accepted answer. Since the function is very small, it is a good candidate for inlining when optimization is turned on. However, if that function were inlined, its return value would be invalid : it would simply return some value of ra
in the calling function, since a jal
or jalr
wouldn't be generated, and ra
thus not set to the instruction following jal
/jalr
. This is why __attribute__((noinline))
is essential in this case.