News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

msdn inline asm mistake?

Started by thomas_remkus, November 29, 2005, 07:15:29 PM

Previous topic - Next topic

thomas_remkus

I am trying to use the code from the MSDN and it's telling me that I have an operand error. Can someone review this?

int main (void)
{
   char format[] = "%s %s\r\n";
   char hello[] = "hello";
   char world[] = "world";

   __asm
   {
      mov eax, offset world
      push eax
      mov eax, offset hello
      push eax
      mov eax, offset format
      push eax
      call printf
      pop ebx
      pop ebx
      pop ebx     
   }

   return 0;
}

Infro_X

local variables must be "moved" into eax with lea (load effective address"

lea eax,[world]

mov eax,offset world ,,,isn't possible because that is mov a DWORD (immediate) into eax.
why, because world is created on the stack (ss:esp points to the stack, the prodecdure creates the stack frame (push ebp; mov ebp,esp; sub esp,(localvariables size)
lea eax,[ebp-xxx] is the same as , mov eax,ebp; sub eax,xxx (for local variables created using a stack frame)


so simply put,
lea eax,[localvars] is how you load the address of a local variable
mov eax,offset gobalvar is how you load the address of a global varible

lea eax,[1] is the same as mov eax,1
lea supports displacement+index*(2^x from 0 to ??)+base

some tips for using lea intresstingly
to times anything by 3,5,9,17,?? you can use lea
lea eax,[eax+eax*2]
lea eax,[eax+eax*4]
lea eax,[eax+eax*8]
lea eax,[eax+eax*16]
as well as use lea to do some simple mathmatics
lea eax,[eax*2+5]
lea eax,[e??*??+???] :)

thomas_remkus

Thanks! That worked perfectly. Of course, if I put the C variables as global I can still use the "lea" operator.

thomas_remkus

Now that I'm back to tinkering with this. I want to understand what it does. I think that I have most of it in my head except for the "pop ebx". Why do I need to do that ... and why three times??

To me, the "load effective address" is putting in a 32 bit register the address of my world variable. Then I push that to the stack because that's how printf will read the parameters (backwards). After the call to printf I don't understand the pop commands.

thomas_remkus

Now, let me try this ... is it because I pushed three times and now I need to pop three times? Why didn't printf pop the variables? And why not pop to eax?

Eóin

Quote from: thomas_remkus on April 06, 2006, 11:42:06 PMWhy didn't printf pop the variables?

Because printf use C calling convention and C call functions don't clean up the stack so the calling code has to. The reason why printf is C call is that it can accept a variable number of arguements hence only the calling code knows how many there were and therefore it knows how many it needs to clean up after.

Quote from: thomas_remkus on April 06, 2006, 11:42:06 PMAnd why not pop to eax?

eax is left holding the return value of printf, pop into it would lose that return.

asmfan

Russia is a weird place

thomas_remkus

I understand your "add esp, 12". it makes sense I think. it's because there are several things are passed on the stack. I don't know exactly what but I think that a return address is one of them or something.

Is the "add esp, 12" faster than three pops? Each pop I think is 1 cycle, so that's 3. The "add" to a register from a constant is 2 cycles?

These just may be stupid questions but I really find your methods interesting. Are they normally used? What happens to the 12 bytes that were no popped? Vaporized? Lost? 4 8 15 16 23 42?

And, what else is on the stack that my application knew to crash because I did not pop three times??????

Mark Jones

"To deny our impulses... foolish; to revel in them, chaos." MCJ 2003.08