An example we can build upon 105 The first thing we do is set up the new stack and write the address to the function we want to run at a 16-byte offset from the top of the stack (the ABI dictates a 16-byte stack alignment, so the top of our stack frame must start at a 16-byte offset). We'll see how to create a continuous piece of memory a little later, but it's a rather straightforward process. Next, we pass the address of the first byte in which we stored this address on our newly created stack to the rsp register (the address we set to new. rsp will point to an address located on our own stack, which in turn is an address that leads to the hello function). Got it? The ret keyword transfers program control to what would normally be the return address located on top of the stack frame it's currently in. Since we placed the address to hello on our new stack and set the rsp register to point to our new stack, the CPU will think rsp now points to the return address of the function it's currently running, but instead, it's pointing to a location on our new stack. When the CPU executes the ret instruction it will pop the first value of the stack (which is conveniently the address to our hello function) and place that address in the rip register for us. On the next cycle, the CPU will fetch the instructions located at that function pointer and start executing those instructions. Since rsp now points to our new stack, it will use that stack going forward. Note If you feel a little confused right now, that's very understandable. These details are hard to understand and get right, and it takes time to get comfortable with how it works. As we'll see later in this chapter, there is a little more data that we need to save and restore (right now, we don't have a way to resume the stack we just swapped from), but the technical details on how the stack swap happens are the same as described previously. Before we explain how we set up the new stack, we'll use this opportunity to go line by line and explain how the inline assembly macro works. An introduction to Rust inline assembly macro We'll use the body of our gt_switch function as a starting point by going through everything step by step. If you haven't used inline assembly before, this might look foreign, but we'll use an extended version of the example later to switch contexts, so we need to understand what's going on. unsafe is a keyword that indicates that Rust cannot enforce the safety guarantees in the function we write. Since we are manipulating the CPU directly, this is most definitely unsafe. The function will also take a pointer to an instance of our Thread Context from which we will only read one field: unsafe gt_switch(new: *const Thread Context)