NASM - The Netwide Assembler
NASM Forum => Using NASM => Topic started by: tomix on January 08, 2011, 06:14:57 PM
-
Hi, I have small function for C in the NASM, that return float value (4.2). This function but return integer value into EAX (0).
Function in NASM:
global _fce
section .text
_fce:
push ebp
mov ebp,esp
finit
fld qword [b]
xor eax,eax
leave
ret
section .data
b: dq 4.2
C program
#include <stdio.h>
extern double _fce();
int main(void)
{
double a=fce();
printf("%lf",a);
return 0;
}
-
What's the problem? With one minor tweak, it "works for me". I had to spell "fce" as "_fce" in the body of "main". It displays more decimal places than intended(?), but it works. Changing the format string to "%.1f" fixes that...
The "xor eax, eax" is probably useless - a function returning "float" or "double" returns the value on the top of the FPU stack, not in eax. (is this "standard"?)
The use of underscores is definitely "non-standard"! For Linux/gcc, we don't need 'em at all. In most cases, you'd want to spell it "fce" in the C file, and "_fce" in the asm file. For WatCom C, you'd spell it "fce_" in the asm file! Nasm provides a feature whereby you can spell it "fce", and add "--prefix _" to the command line, and Nasm will put an underscore on anything "extern" or "global". ("-- postfix _" for WatCom).
If you can't get it working, you may need to tell us exactly what happens... and perhaps "what kind of C" as well.
Best,
Frank
-
You're right. I had try program in the linux and program works correctly (output is 4.2 from st0). But in the windows is problem (output is 0.0 from EAX).
In the windows I use:
MinGW - gcc version 4.4.1
NASM 2.10rc1
I use prefix for elf file in Windows OS, because gcc (under win32) isnt add "_" prefix.
-
Well... I can't help ya with Windows. Ask MS. That's really strange! Returning a single-precision float in eax is... possible, at least. Returning a double in eax just isn't possible. edx:eax maybe... I doubt it. Are you sure that's what's happening? What happens if you return -1 in eax?
I observe that scanf() takes the address of a float/double as a parameter. You could try modifying your files to do it that way...
#include <stdio.h>
extern int fce(double *);
int main(void)
{
double a;
fce(&a);
printf("%.1f\n",a);
return 0;
}
; this version takes a "place to put it" as a parameter
; for Linux:
; nasm -elf32 myfile.asm
; for Windows:
; nasm -f win32 --prefix _ myfile.asm
; ?
global fce
section .text
fce:
push ebp
mov ebp,esp
mov eax, [ebp + 8]
finit
fld qword [b]
fstp qword [eax]
xor eax,eax
leave
ret
section .data
b: dq 4.2
As you see, I eliminated the underscores entirely. You can put 'em back in, if you want. I don't know if this would be "appropriate" for you or not. Works for Linux, "should" work for Windows(?)...
Best,
Frank
-
I try your code,now return value is very strange:1.$
For compile I used your argument: nasm -f win32 --prefix _ pr3.asm
When I try compile with: nasm -f elf --prefix _ pr3.asm
return value is good !!! 4.2
But why dont use this function for return direct float (double) (without pointer) ?
When I try return in the eax (-1) in my first program, return this value -1 (again in eax).
Program in C absolutely ignore return value in stack top (st0).
-
The "xor eax, eax" is probably useless - a function returning "float" or "double" returns the value on the top of the FPU stack, not in eax. (is this "standard"?)
In 32-bit mode, st0 (top of stack) will contain the return value - eax is not used and in this case is "useless"
The use of underscores is definitely "non-standard"! For Linux/gcc, we don't need 'em at all. In most cases, you'd want to spell it "fce" in the C file, and "_fce" in the asm file. For WatCom C, you'd spell it "fce_" in the asm file! Nasm provides a feature whereby you can spell it "fce", and add "--prefix _" to the command line, and Nasm will put an underscore on anything "extern" or "global". ("-- postfix _" for WatCom).
If you can't get it working, you may need to tell us exactly what happens... and perhaps "what kind of C" as well.
As Frank points out, don't add the underscore in your C file. Using different compilers results in various naming conventions depending on the compiler used. As I normally use VC or gcc I usually prepend the underscore to my global assembly function. I probably should get into the habit of not doing that and let nasm handle the prefix/postfix issue from the command line for code that could possibly be used in conjunction with WatCom. But old habits die hard...
You're right. I had try program in the linux and program works correctly (output is 4.2 from st0). But in the windows is problem (output is 0.0 from EAX).
Pay close attention to your prototype:
Instruct the compiler to return an int value in EAX
extern int fce();
Instruct the compiler to return a double in st0
extern double fce();
Remember that fstp will pop the fpu stack in your assembly code. Don't issue this opcode as your last floating point operation in a function that is defined to return a double as the compiler will expect the function result there! ;)