-1

I'm writing a multi-module application (c++ and assembly). I want to make a function with non-integer variables (for example float) using a __cdcel:

extern "C" float __cdecl foo(float* arr, float a, float b );

What should I write to use these variables in assembly code

.586
PUBLIC _foo
.model flat
.code 
_foo proc 
;...
;I want to use my arr, a and b here
;...
ret 
_foo endp
end

It's clear for me, that if my variables were integer, I would use ebp, but in my case I have floats, so what should I write? I'm using Intel x86 ASM

Yauhen Mardan
  • 327
  • 3
  • 10
  • You forgot to specify what environment you are in. Anyway, consult the appropriate calling convention documentation on argument passing. Presumably they will be passed on the stack but returned in `st0`. Also brush up on your x87 knowledge (unless you want to use SSE) – Jester Jun 06 '18 at 22:58
  • 1
    let your compiler create the assembly code for you ;) – skeller Jun 06 '18 at 22:59
  • https://msdn.microsoft.com/en-us/library/zkwh89ks.aspx. `float` args are on the stack. Look at compiler-generated asm for a simple `foo` with that signature and see where it loads args from and where it puts the return value. See also Agner Fog's calling conventions doc: http://agner.org/optimize/ and calling convention links in https://stackoverflow.com/tags/x86/info. – Peter Cordes Jun 06 '18 at 23:13
  • Search for "cdecl" on the linked duplicate, Russel's answer (copied from wikipedia) says args are on the stack. That includes `float` args. – Peter Cordes Jun 07 '18 at 06:14

1 Answers1

-2

You will get three floats passed to ASM in XMM0, 1, 2, and 3. Set a break point before calling the function in C++, then F11 to go into ASM and check registers where you have passed values.

See Calling Conventions Have a look atCompiling 64-bit Assembler Code in Visual Studio

John Deere
  • 29
  • 1
  • 4
  • 1
    His code is 32-bit (examine the assembly he posted) and he does say `x86` (not `x86-64`) so his C code follows the 32-bit x86 cdecl calling convention for Windows, and which his function has to be written for. In that case floats along with the integer class values are pushed on the stack right to left. – Michael Petch Jun 07 '18 at 00:49
  • That applies to `__fastcall` and `__vectorcall` in 32-bit mode, and the conventions of the same name in 64-bit mode. But *not* 32-bit `__cdecl`, which doesn't require SSE. Also, one of the args is a `float*`, not a `float`, so it's an integer/pointer. – Peter Cordes Jun 07 '18 at 00:59
  • I overlooked x86. In today's world of 64bit processors it is much easier to use x64 ASM in Visual Studio 2017. He will get integer pointer in RCX, and two floats in MM0 and 1. – John Deere Jun 07 '18 at 01:24
  • Yes, agreed that x86-64 is generally easier, and that register-arg calling conventions are better. I'd recommend that, too, instead of obsolete 32-bit code with crappy stack-args calling conventions especially for new development. But it's not like the x86-64 Windows convention is super simple. You'd get args in XMM1 and 2, because the first arg is an integer. Unlike x86-64 SysV, only the first 4 total args can go in regs. (And BTW, MM0 is a 64-bit vector register that aliases the x87 registers.) But anyway, this is the wrong answer to *this* question. It could be part of an answer... – Peter Cordes Jun 07 '18 at 06:12