July 11th, 2024

Run Functions in Another Stack with Zig

Alessio Marchetti discusses running functions in a separate stack using Zig, covering stack pointer manipulation in assembly code, optimized code generation, and a detailed Fibonacci function example. Emphasizing learning through experimentation without optimization flags.

Read original articleLink Icon
Run Functions in Another Stack with Zig

Alessio Marchetti shares insights on running functions in another stack using Zig. The blog post delves into manipulating stack pointers in assembly code, explaining concepts like labels, instructions, and data handling. Alessio demonstrates a simple function and its corresponding assembly code, highlighting stack manipulation steps. The post also explores optimized code generation and explicit stack pointer manipulation techniques. Alessio presents a detailed example involving a Fibonacci function and a wrapper function to call it from a separate stack. The code allocates a new stack, saves stack pointers, copies stack frames, executes the function, and restores the original stack state. The post emphasizes experimentation with low-level code for learning purposes and concludes with a reminder not to compile the final code with optimization flags. Alessio's engaging narrative encourages readers to explore and understand the intricacies of programming.

Related

Microbenchmarking Return Address Branch Prediction (2018)

Microbenchmarking Return Address Branch Prediction (2018)

Modern processors use branch predictors like RAS to boost performance by predicting control flow. Microbenchmarking on Intel and AMD processors reveals RAS behavior, accuracy, and limitations, emphasizing accurate branch prediction for high performance.

Mix-testing: revealing a new class of compiler bugs

Mix-testing: revealing a new class of compiler bugs

A new "mix testing" approach uncovers compiler bugs by compiling test fragments with different compilers. Examples show issues in x86 and Arm architectures, emphasizing the importance of maintaining instruction ordering. Luke Geeson developed a tool to explore compiler combinations, identifying bugs and highlighting the need for clearer guidelines.

Weekend projects: getting silly with C

Weekend projects: getting silly with C

The C programming language's simplicity and expressiveness, despite quirks, influence other languages. Unconventional code structures showcase creativity and flexibility, promoting unique coding practices. Subscription for related content is encouraged.

Do not taunt happy fun branch predictor

Do not taunt happy fun branch predictor

The author shares insights on optimizing AArch64 assembly code by reducing jumps in loops. Replacing ret with br x30 improved performance, leading to an 8.8x speed increase. Considerations on branch prediction and SIMD instructions are discussed.

Beating the Compiler

Beating the Compiler

The blog post discusses optimizing interpreters in assembly to outperform compilers. By enhancing the Uxn CPU interpreter, a 10-20% speedup was achieved through efficient assembly implementations and techniques inspired by LuaJIT.

Link Icon 3 comments
By @AndyKelley - 7 months
Fun fact: zig used to have a `@newStackCall` builtin [1], removed from the language in 0.6.0 [2].

[1]: https://ziglang.org/documentation/0.5.0/#newStackCall

[2]: https://ziglang.org/download/0.6.0/release-notes.html#newSta...

By @8474_s - 7 months
Why not bypass this nasty stack juggling and just use a async/await?
By @Teiolass - 7 months
Every program compiled with a reasonable compiler runs putting some of its data in the so called stack. It’s fairly easy: when you call a function, the function puts its data on top of the stack; when the function returns the data is removed so that the stacks now exposes the data of the caller function. In this post we mess with this mechanism, but substituting the default area of memory for the stack with a freshly allocated one.