In my university project i have to use binary representation of float number in x86 assembly for arithmetic operations. Using FPU is forbidden so i try to read float number and return it as DWORD but whatever i try to do i get "-nan". Any advices?
Edit: I use gcc and it's 32 bit code
Declaration in C (i can't change that)
extern "C" float func(float num);
*.asm file
section .text
global func
func:
;prolog
push ebp
mov ebp, esp
; zapamiętanie rejestrów zachowywanych
push ebx
push esi
push edi
mov eax, DWORD [ebp+8]
;mov eax, 0xffffffff i checked that but i still get the same result
; odtworzenie rejestrów, które były zapamiętane
pop edi
pop esi
pop ebx
;epilog
pop ebp
ret
Example result (for 256)
01000011100000000000000000000000
11111111110000000000000000000000
num1: 256.000000
num2: -nan
Edit:
C code without checking bits part
#include <stdio.h>
extern "C" float func(float num);
int main()
{
float num1;
float num2;
scanf("%f", &num1);
num2=func(num1);
printf("num1: %f\nnum2: %f\n", num1, num2);
return 0;
}
If you declare the return type func as float
the result will be returned in the FPU (ST0). For returning a value in EAX
you have to declare it as an integer type. For printf
you have to fake a float. Example:
caller.c:
#include <stdio.h>
#include <stdint.h>
extern float asmfunc1(float);
extern uint32_t asmfunc2(float);
int main (void)
{
printf ("asmfunc1: %f\n", asmfunc1(456.78));
uint32_t ifl = asmfunc2(123.45);
float* pfl = (float*) &ifl; // Faking a float
printf ("asmfunc2: %f\n", *pfl);
return 0;
}
callee.asm:
section .text
global asmfunc1, asmfunc2
asmfunc1:
fld dword [esp+4]
ret
asmfunc2:
push ebp
mov ebp, esp
mov eax, [ebp+8]
leave
ret
Build & run:
nasm -felf callee.asm
gcc -m32 callee.o caller.c
./a.out
In the 32 bit Linux ABI, float
values are actually returned as long double
at the top of the 8087 FP stack. You cannot return a float
without using the FPU.
What you are probably restricted from doing is FP operations for addition, subtraction... But you still need to load the result in the FP stack to return it. In 64 bits mode, you would return float
values as double
in the xmm0
register.
Try changing the code to this:
section .text
global func
func:
push ebp
mov ebp, esp
flds 8(%ebp)
pop ebp
ret
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.