call8 and a0 (access / modify the return address)

vvb333007
Posts: 71
Joined: Wed Jul 31, 2024 5:53 am
Location: Thailand
Contact:

call8 and a0 (access / modify the return address)

Postby vvb333007 » Tue Sep 23, 2025 9:29 am

Hello!

Was reading about windowed calling conventions and found that a0, the return address is not accessible from within called function. E.g. if I would like to modify the return address, should I:
1. Manually move window left, change a0, move window right or
2. Provoke window spill, make a few nested dummy function calls, so my a0 can be found on the stack and modified there

I am asking this just for better understanding of how it all works. Xtensa is new for me so I want to learn the basics.

Also, regarding "entry aX, N"

Am I right in the assumption that it is "entry" who actually rotates the window, so register a0 (return address) is accessible from the called function before "entry" call? I.e. if I change function prologue from "entry aX, N" to

mov a13, a0
entry ...

then I can get my return address value in a13 (which becomes a5 after rotation by 8)
Is this correct?

Thank you!
Thanks!
Slava.

vvb333007
Posts: 71
Joined: Wed Jul 31, 2024 5:53 am
Location: Thailand
Contact:

Re: call8 and a0 (access / modify the return address)

Postby vvb333007 » Tue Sep 23, 2025 10:35 am

Espressif documentation:
With all the necessary points covered, let’s take an example and connect all the dots.
Suppose, each function call is carried out using call8 and we start with WindowBase = 4

Function A calls B, B calls C, C calls D... till I, i.e:

Functions A -> B -> C -> D -> E -> F -> G -> H ->I
WindowBase 4 -> 6 -> 8 -> 10 -> 12 -> 14 -> 0 -> 2 -> 4

On each function call, the WindowBase will be incremented by 2 because call8 is used.
No. of bits in WindowBase register = log2((No. of registers in register file)/4) = log2(64/4) = 4.
Thus the max value of WindowBase is 15.
As we have noticed, on the 9th function call the window wraps around to a point where the frame
contains the data of a parent function, i.e a0, a1.. contains data of A. It implies that a8, a9.. of H
are a0, a1.. of A.


A window overflow exception will be generated when H tries to modify a8, a9.. since it originally
contains the context of A,
so these must be saved to accommodate arguments of I. At this point, in
the window overflow exception handler we must rotate the register window to frame A (WindowBase
= 4)

a0 – a3 are stored in the Base Save Area of B’s stack frame. B’s stack frame is accessible since a9
is a1 of B, which is B’s stack pointer.
a4 – a7 are stored in the Extra Save Area of A’s stack frame.
Now whenever B returns, window underflow exception will be generated and we need to make sure
that the corresponding exception handler would restore these values back into the registers.
Is this correct? It says, that after call to H, register window now is in area of A.
Then it says "whenever function B returns" (??) did they mean H or I ? When H calls I, then window will be the same as for B, so exception overflow occurs again?

It implies that a8, a9.. of H
are a0, a1.. of A.
and then : "B’s stack frame is accessible since a9
is a1 of B, which is B’s stack pointer."

So.... a9 of H is a1 of A or a1 of B? Or it is a mistake in the doc?
Thanks!
Slava.

MicroController
Posts: 2669
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: call8 and a0 (access / modify the return address)

Postby MicroController » Tue Sep 23, 2025 11:18 am

https://www.cadence.com/content/dam/cad ... ummary.pdf
The CALL8 instruction does not rotate the window itself, but instead stores the window increment for later use by the ENTRY instruction. The return address and window increment are placed in the caller’s a8 (the callee’s a0), and the processor then branches to the target address.

MicroController
Posts: 2669
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: call8 and a0 (access / modify the return address)

Postby MicroController » Tue Sep 23, 2025 11:44 am

Then it says "whenever function B returns" (??) did they mean H or I ?
When the window overflow occurs, the WindowStart is moved (up), so A is pushed out of the window. When B returns (to A), a window underflow occurs and the WindowStart has to be moved down again.
Last edited by MicroController on Wed Sep 24, 2025 6:38 pm, edited 1 time in total.

vvb333007
Posts: 71
Joined: Wed Jul 31, 2024 5:53 am
Location: Thailand
Contact:

Re: call8 and a0 (access / modify the return address)

Postby vvb333007 » Tue Sep 23, 2025 12:25 pm

Then it says "whenever function B returns" (??) did they mean H or I ?
When the window overflow occurs, the WindowBase is moved (up), so A is pushed out of the window. When B returns (to A), a window underflow occurs and the WindowBase has to be moved down again.
In this scheme:

Functions A -> B -> C -> D -> E -> F -> G -> H ->I
WindowBase 4 -> 6 -> 8 -> 10 -> 12 -> 14 -> 0 -> 2 -> 4

Overflow occurs when H calls I. As a result, window is moved to the A, but registers a0..a7 of A are saved to the stack by the window overflow handler, is it correct?

Suppose function I calls another function K. Window moves to the right, to position of B and? Overflow happens again? If not, then registers of B will be overwritten by K.

Totally lost.
Thanks!
Slava.

MicroController
Posts: 2669
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: call8 and a0 (access / modify the return address)

Postby MicroController » Tue Sep 23, 2025 3:23 pm

Overflow occurs when H calls I. As a result, window is moved to the A, but registers a0..a7 of A are saved to the stack by the window overflow handler, is it correct?

Suppose function I calls another function K. Window moves to the right, to position of B and? Overflow happens again?
... and registers a0...a7 of B will be saved to the stack by the overflow exception handler and the WindowStart moved up again, correct.

Btw, since the IDF already comes with the window exception handler you don't really need to bother about the workings. You only need to know the ABI, i.e. CALL8, i.e. caller's a8...a15 become callee's a0...a7; caller and callee share only 8 registers.

Who is online

Users browsing this forum: Applebot, Bing [Bot], Qwantbot, YisouSpider and 3 guests