stationeers.de Mod workshop · Dominik1199
DE Sign in
  1. Home
  2. IC10 academy
  3. Day 128

Day 128 of 365 · Advanced · Month 5: Memory and structure

Nested calls

If a subroutine calls a second one, jal overwrites ra. push ra at the start and pop ra before returning save the return ticket.

Lesson 13 min Week 19

What you learn today

  • Save ra on the stack
  • pop ra before returning
  • Limit the depth

The subroutine check shows the temperature and warns about cold. For the conversion it calls a second subroutine itself, celsius. As soon as that is built in, the chip never gets back to the main loop.

What happens to ra

jal writes the return address into one single register: ra. If check calls a second subroutine with jal celsius, it overwrites the address the main loop left there. The j ra at the end of check then does not jump back into the main loop but behind jal celsius, that is into the middle of check. The chip runs in a circle without ever reaching a yield.

Saving ra on the stack

The solution: every subroutine that uses jal itself puts ra on the stack on entry and fetches it back before returning.

check:
push ra          # save the return ticket
jal celsius      # overwrites ra
sbn DISPLAY HASH("Labortemp") Setting c
pop ra           # return ticket back
j ra

celsius does not call anything further. It needs no push ra, its j ra leads cleanly back into check.

Limiting the depth

Every level that saves ra occupies one slot in the stack until it returns. Three levels are three slots, that is harmless. It becomes dangerous when a subroutine calls itself and never stops: then the stack grows until StackOverFlow.

Keep the depth small, two or three levels are enough for almost everything. Deeply nested code is hard for people to follow as well.

Warning

push ra and pop ra must come in pairs on every path through the subroutine. If one path leaves with j ra without pop ra, neither ra nor sp is right afterwards.

Tip

If the subroutine itself uses push and pop for intermediate values, the same rule applies: whatever it puts on, it takes off again before the pop ra. Otherwise pop ra fetches the wrong value.

Diagram

Calling and returning from a subroutine Main loop 2 l r0 d0 Temperature 3 jal celsius 4 s d2 Setting r1 5 l r0 d1 Temperature 6 jal celsius 7 s d3 Setting r1 8 j start celsius: sub r1 r0 273.15 j ra ra = 4 back to line ra
Every level puts its ra on the stack and fetches it back before j ra. That way every level finds its way home.

Exercise

Task

In the editor the main loop calls the subroutine check, and check calls celsius. As the code stands, the chip never returns to the main loop.

  • Save ra in check with push ra and fetch it back with pop ra before returning.
  • LED “Labortemp” shows the temperature of the gas sensor “Labor” in °C, −999 without a sensor.
  • Flashing light “Laborwarnung” on below 10 °C and on sensor failure. After every pass sp is 0 again.

Hints

Hint 1

Play the flow through: what is in ra when check reaches its j ra?

Hint 2

push ra belongs at the start of check, before jal celsius.

Hint 3

pop ra right before the j ra of check.

Quiz

4 questions. You pass from 60 % – the server does the grading.

Complete the day

  • Passed the simulator exercise
  • Passed the quiz with at least 60 %

Without an account progress is saved in this browser only.

Report a mistake in this lesson

Please sign in to report. Sign in

Esc
↑ ↓ selectEnter open/ opens search anywhere