0

I'm new to assembly (using fasm), but pretty familiar with C. But my floating point code always return 0. I have tried using the FPU instruction set, and the SSE instruction set, but the result is always 0.0000 and I'm not sure what I'm missing. Here's what I have:

section .data

fmt db 'fv = %f',0ah,0

fv dd 5.0f
fv2 dd 2.0f

section .text
_main:

enter 0,0
    ; // fv*=fv2;
    movss xmm0,[fv]
    movss xmm1,[fv2]
    mulss xmm0,xmm1
    movss [fv],xmm0

push [fv]
push fmt
call _printf

However, using the Microsoft Visual C compiler and inline-assembly, the same code seems to work. Here's the applicable portion:

__asm
{
    ; // fv*=fv2;
    movss xmm0,[fv]
    movss xmm1,[fv2]
    mulss xmm0,xmm1
    movss [fv],xmm0
}

...printf("fv = %f\n",fv);
C. Dunn
  • 101
  • 1
  • 6
  • 1
    Are you programming in 32 bit mode or in 64 bit mode? What architecture and operating system are you programming for? – fuz Mar 23 '18 at 12:27
  • 3
    `printf` is a varargs function, as such `float` arguments are promoted to `double`. The C compiler does that for you, but your assembly version doesn't. The [linux man page](http://man7.org/linux/man-pages/man3/printf.3.html) is quite specific about it too: _"f, F The double argument ..."_ – Jester Mar 23 '18 at 12:47
  • Use `sub esp, 8` / `movsd [esp], xmm0` to store a `double` to the stack. The linked duplicate explains why you got zero; presumably there's a `0` dword on the stack above the `float` you push, giving you the same situation as with a `float` in `xmm0` being interpreted as `double` by a register-args printf. Use a debugger to find out. (I'm assuming you're building the FASM version as 32-bit, too, to match the MSVC version, but maybe fuz is right to ask. If it's 64-bit, that's not how you pass args to functions!) – Peter Cordes Mar 23 '18 at 14:31
  • Thanks everyone so much. I got it working now! I read your explanation on the 'original' question, Peter. I had no idea var-args lists did that. I also verified that I am indeed using 32-bit mode (changing it to 64-bit broke the program...). If it isn't too much, could you explain why you can't just use `push qword[var]` instead of moving esp? – C. Dunn Mar 24 '18 at 01:40
  • 32-bit mode can't use 64-bit operand-size! qword integer operations like `add`, `mov` and `push` (not just SSE `movlps` and SSE2 `movsd` / `movq`) were why AMD64 / x86-64 was designed! (As well as 64-bit addressing modes so you can address more than 4GiB of RAM). – Peter Cordes Mar 24 '18 at 02:09

0 Answers0