3

I've been playing around with inline assembly in Visual C++ lately and i was wondering if i could directly add a value to a local variable on the stack, for example:

push 5
add [esp], 7

Is it okay to do this? I'm asking cause I've had some weird issues at random doing this (though most of the time it works fine), however if i go through a register i never have any problem, like so:

push 5
mov eax, [esp]
add eax, 7
mov [esp], eax
Matt Busche
  • 14,216
  • 5
  • 36
  • 61

1 Answers1

0

As Vlad Krasnov has said in a comment on the question, the problem comes from the compiler (and/or the assembler) not knowing the size of the arguments in code like add [esp], 7. This problem wouldn't arise if you were writing, for example, add [esp], eax.

If you were the compiler, how would you interpret this instruction? You are asked to add 7 to the memory location ESP is pointing to. But neither 7, nor [esp] specify how large the arguments for the addition are. A byte? Two bytes? Four bytes? Even 8 bytes would have been a possibility if this wasn't inline assembly (isn't allowed in 64-bit code.)

Note that while ESP is 4 bytes, the memory location it points to can be of any size. The same goes for the immediate value 7, which can fit in any number of bytes.

The solution, as again is mentioned by Vlad Krasnov in the comments is to specify the size of the operand explicitly. You can check your favorite assembler's documentation, but in this case, if you want 32-bit addition, you can write add DWORD PTR [esp], 7. This obviously says that [esp] points to a DWORD in memory (which is 32 bits for MASM.)

Also note that not all instructions on x86 support a form that have immediate values and memory addresses in them. For each instruction, you could check "Intel Architectures Software Developer Manual", volume 2 (which is the instruction set reference) to make sure the instruction you are trying to use actually exists!

And, you should always inspect the assembly output of the compiler (since you are working with inline assembly) to make sure the code the compiler generated is actually what you intended. It is quite easy to instruct the compiler to generate assembler code, and it's quite readable!

yzt
  • 8,873
  • 1
  • 35
  • 44