Add a variable to the stack in x86 assembly

assembly, local-variables, x86, x86-16

Solution

If you want to store a variable on the stack, you need to reserve space for it, this is generally done with the `SUB ESP,xxx` sequence, where `xxx` is the size of the "variable" you want to make space for, aligned to the stack alignment (generally 4 bytes, can also be 8 or 16). The only exception to this rule is when the variable is in a register, in which case you can perform a `PUSH` on that register.

This space needs to be cleaned up on function exit, so if you `PUSH`ed a register, you should `POP` it or, `ADD ESP,xxx` where `xxx` was the size you originally `SUB`'ed/the size of the register you `PUSH`ed aligned to the stack size.

Reading and writing are done using `MOV`, but this is where it gets a little tricky, as we have two cases, with stack frames, and without stack frames.

without stack frames requires more math, as you need to compensate for the function arguments on the stack, so if our function takes 2 args, and we allocate space for an integer on the stack, we can write to it via `MOV [ESP + 0xC],value`, reading is the same `MOV EAX,[ESP + 0xC]`.

with a stack frame, your arguments take a positive index to `EBP` and your allocated memory is negatively indexed from `EBP`, so with the same example above, you'd do `MOV EAX,[EBP-4]`.

As you can see this gets a little tricky, so a better way is to create C or C++ code that represents what you want, compile it with `-O0` (we compile with no optimization to prevent elision of stack vars to registers) then dissassemble it, and see how the compiler does it.

Problem

I wonder, how to set a local variable in ASM's procedure ? thanks!!

Original source