0

I am using Visual Studio 2017 and compiling for 32-bit.

Say I have the following code snippet. The statements which don't compile give "invalid operand" errors.

int localVar = 0;
__asm {
    mov eax,      [esp+4]         <----- compiles
    mov localVar,  esp            <----- compiles
    mov localVar, [esp]           <----- doesn't compile
    mov localVar, [esp+4]         <----- doesn't compile
}

I'm aware that the 2nd and 3rd statement aren't equivalent, but I wanted to highlight the following point...

Essentially it appears that if I'm using brackets around the second operand in this manner AND storing the results into a local variable it doesn't work. I was under the impression using brackets like that was valid syntax, as proven by the first statement which stores the result into eax.

I have speculated it might be something to do with my variable type and I have tried to change mov to movl but that doesn't work either.

Basically my ultimate goal is for this to work properly: mov localVar, [esp+4] How do i achieve this? The type of localVar doesn't have to be int... I just thought that should work.

noobcoder
  • 6,089
  • 2
  • 18
  • 34
  • 1
    You can move from memory to a register, or from a register to memory, but you can't move directly from memory to memory. – Barmar Apr 12 '17 at 20:54

1 Answers1

2

x86 instruction set does not have memory to memory move instruction. All instructions involve either two registers or one register and a memory location. The variable localVar is a memory location. Essentially what you are writing is:

movdw [ebp-4], [esp+4]

Instead you should have:

mov eax, [esp+4]
mov localVar, eax
P. Kouvarakis
  • 1,893
  • 12
  • 21