Jump to line of code in C using pointers (not goto)?

Viewed 206

I know this is a strange question but is there a way to use pointers to return to a certain point in the code? What I'm trying to do is mimic the behavior of a jal instruction in MIPS.

For instance, if I have a function fun1() that returns 1, and another function fun2() that returns 2, and main() as defined here:

1  main() {
2   int v = fun1(); // v = 1
3   if (v == 2) return 2;
4   v = fun2(); // v = 2
5  }

Could I jump back to line 3 after fun2() is called in line 4 by keeping a pointer to the return address of the call to fun1 on line 2?

1 Answers

With the GNU C extension to take the address of a goto label (https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html), yes, you could emulate a jal-like function call using a C variable as the "link register" like asm $ra. But that's separate from the asm the compiler emits - you'd have to make the "function calls" using goto to do exactly what you describe.

No, you can't hack into the asm the compiler emits and capture the return address. That's not something you can safely do even with GNU C inline asm.

Also, IIRC, the standard MIPS calling convention doesn't require functions to return by restoring the return address into RA. In theory they could return with jr $t9 or whatever after copying the return address to that register instead of $ra. The caller can't assume anything about RA on return from a jal. In practice, though, RA will hold the value JAL put there. I can't think of any reason the compiler would do something different. Except maybe C++ exception unwinding? But that would end in a catch, not in the normal return path.

So sure, if you were writing the caller in asm, you could take advantage of $ra if you wanted, although normally it would be no more efficient than a normal relative-branch bne $v0, $s0 instruction at the bottom of a while loop containing a jal fun2 to keep calling until you got a different return value.

Related