Tower of Alloy and Passing Stack Arguments

Tower of Alloy and Passing Stack Arguments

Introduction

This guide will cover the basics on how to implement a working call stack that has the ability to pass function parameters. This is neccesary to complete Tower of Alloy, and to create a working computer. I couldn't really find a guide online that covers the process so here's my approach.

How Does The Call Stack Really Work?


Tower of Alloy and Passing Stack Arguments image 3
Tower of Alloy and Passing Stack Arguments image 4
Tower of Alloy and Passing Stack Arguments image 5

Turing Complete already gives you the basic example of how a call stack is supposed to work. In a nutshell, it's memory linked to a counter that increments when a value is added, and this value happens to be the instruction pointer (+1) to the caller function. The "ret" command pops the value off the stack, gives it back, and the program jumps to that value.

Local variablesLocal variables inside a call stack are simpler than you think. The function just pushes values onto the stack, then is required to pop all of them when its instruction has ended.

It is IMPORTANT you pop all local variables after the function ended, otherwise your program will jump to undesirable locations!

Example code that adds 2 numbers together, 50 and 60

Passing argumentsOkay so now the tricky part - In the previous example, you could add 50 and 60 together. But what if we want to define which numbers to add together? We want to turn it into a function that gets two parameters, adds them, then stores the output in the ecx registry (for now). Our "C" code would look like this:

void add(int a, int b) { ecx = a + b; } add(13, 37);

Sounds simple enough, right? Just store the variables 13 and 37 into the eax and ebx registry before calling the function. Pseudoassembly:

jump main add2: add eax,ebx ecx ret main: move $13, eax move $37, ebx call add2

While this works in theory, this means you cannot access the eax and ebx registries until the function is done with them. This will give problems to a simple edge case: What if the function is nested? This is exactly the problem of Tower of Alloy - You're supposed to write a recursive function with multiple arguments. A recursive function is basically a nested function that calls itself.You can find more about it online.

Example:

add3: mov $100, eax # eax is now corrupted! add eax,ebx ecx # ecx is now corrupted! ... ret a: mov $10, eax mov $20, ebx mov $30, ecx call add3 ret

You can fix this by passing the arguments directly onto the stack, and copying the results using the stack pointer (value that points to the top of the stack) decremented by the value you want. This way the aguments for the function will be immutable!

Wrapping it all togetherWhen the function has finished executing (after ret jumped back), it's important to reset the stack pointer back to its original position. In my example, I just popped off all the arguments from the call stack, however it's also possible to decrement the stack pointer. Just keep in mind that the "stack" just moves items to where the stack pointer points at, then increments the SP by 1!

The next section will go in depth about the component used.

The Component


Tower of Alloy and Passing Stack Arguments image 21

Below is the component I've used to create the program. (Ignore the OFF switches, they're just for component aesthetics)

EnableEnables the component.

PushPUSHes value onto the stack, and increments the SP by 1.

PopDecrements the SP by 1 and outputs the value on the stack pointed by SP.

ReadREADs the value of the stack with negative offset value (SP-value). Will not alter the SP.

With this component, you should be able to implement stack arguments into your call stack. Keep in mind there's still room for more ideas, such as decrementing the SP instead of popping off all arguments after a function has finished its routine.

Conclusion

I hope this guide has helped you out a little to understand how the (simplified) call stack really works. There's plenty of guides online, though they always seem to focus a bit too much on the assembly language itself.

Feel free to use the component.

Source: https://steamcommunity.com/sharedfiles/filedetails/?id=2876411480					

More Turing Complete guilds