浮点类型的返回值比较特殊,它不像整数或字符串类型的返回值,可以存储在EAX寄存器里,对于C风格的汇编函数,浮点类型的返回值需要存储在ST(0)的浮点寄存器里。调用这类函数的程式,需要负责将返回值从ST(0)里提取出来...
float function1(float, float, int); |
double function1(double, int); |
# areafunc.s - An example of a floating point return value .section .text .type areafunc, @function .globl areafunc areafunc: pushl %ebp movl %esp, %ebp fldpi filds 8(%ebp) fmul %st(0), %st(0) fmul %st(1), %st(0) movl %ebp, %esp popl %ebp ret |
/* floattest.c - An example of using floating point return values */
#include <stdio.h>
float areafunc(int);
int main()
{
int radius = 10;
float result;
result = areafunc(radius);
printf("The result is %f\n", result);
result = areafunc(2);
printf("The result is %f\n", result);
return 0;
}
|
$ as -o areafunc.o areafunc.s $ gcc -o floattest floattest.c areafunc.o $ ./floattest The result is 314.159271 The result is 12.566371 $ |
int i = 10; int j = 20; result = function1(i, j); |
# greater.s - An example of using multiple input values .section .text .globl greater greater: pushl %ebp movl %esp, %ebp movl 8(%ebp), %eax movl 12(%ebp), %ecx cmpl %ecx, %eax jge end movl %ecx, %eax end: movl %ebp, %esp popl %ebp ret |
/* multtest.c - An example of using multiple input values */
#include <stdio.h>
int main()
{
int i = 10;
int j = 20;
int k = greater(i, j);
printf("The larger value is %d\n", k);
return 0;
}
|
$ as -o greater.o greater.s $ gcc -o multtest multtest.c greater.o $ ./multtest The larger value is 20 $ |
# testfunc.s - An example of reading input values wrong .section .text .type testfunc, @function .globl testfunc testfunc: pushl %ebp movl %esp, %ebp fldl 8(%ebp) fimul 16(%ebp) movl %ebp, %esp popl %ebp ret |
/* badprog.c - An example of passing input values in the wrong order */
#include <stdio.h>
double testfunc(int, double);
int main()
{
int i = 10;
double j = 3.14159;
double result;
result = testfunc(i, j);
printf("The bad result is %g\n", result);
return 0;
}
|
$ as -o testfunc.o testfunc.s $ gcc -o badprog badprog.c testfunc.o $ ./badprog The bad result is -9.29127e+235 $ |
/* goodprog.c - An example of passing input values in the proper order */
#include <stdio.h>
double testfunc(double, int);
int main()
{
double data1 = 3.14159;
int data2 = 10;
double result;
result = testfunc(data1, data2);
printf("The proper result is %f\n", result);
return 0;
}
|
$ gcc -o goodprog goodprog.c testfunc.o $ ./goodprog The proper result is 31.415900 $ |
# fpmathfunc.s - An example of reading multiple input values .section .text .type fpmathfunc, @function .globl fpmathfunc fpmathfunc: pushl %ebp movl %esp, %ebp flds 8(%ebp) fidiv 12(%ebp) flds 16(%ebp) flds 20(%ebp) fmul %st(1), %st(0) fadd %st(2), %st(0) flds 24(%ebp) fimul 28(%ebp) flds 32(%ebp) flds 36(%ebp) fdivrp fsubr %st(1), %st(0) fdivr %st(2), %st(0) movl %ebp, %esp popl %ebp ret |
/* mathtest.c - An example of using multiple input values */
#include <stdio.h>
float fpmathfunc(float, int, float, float, float, int, float, float);
int main()
{
float value1 = 43.65;
int value2 = 22;
float value3 = 76.34;
float value4 = 3.1;
float value5 = 12.43;
int value6 = 6;
float value7 = 140.2;
float value8 = 94.21;
float result;
result = fpmathfunc(value1, value2, value3, value4,
value5, value6, value7, value8);
printf("The final result is %f\n", result);
return 0;
}
|
$ as -o fpmathfunc.o fpmathfunc.s $ gcc -o mathtest mathtest.c fpmathfunc.o $ ./mathtest The final result is 3.264907 $ |
extern "C" { int square(int); float areafunc(int); char *cpuidfunc(); } |
# square.s - An example of a function that returns an integer value
.type square, @function
.globl square
square:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
imull %eax, %eax
movl %ebp, %esp
popl %ebp
ret
|
# areafunc.s - An example of a floating point return value
.section .text
.type areafunc, @function
.globl areafunc
areafunc:
pushl %ebp
movl %esp, %ebp
fldpi
filds 8(%ebp)
fmul %st(0), %st(0)
fmul %st(1), %st(0)
movl %ebp, %esp
popl %ebp
ret
|
# cpuidfunc.s - An example of returning a string value
.section .bss
.comm output, 13
.section .text
.type cpuidfunc, @function
.globl cpuidfunc
cpuidfunc:
pushl %ebp
movl %esp, %ebp
pushl %ebx
movl $0, %eax
cpuid
movl $output, %edi
movl %ebx, (%edi)
movl %edx, 4(%edi)
movl %ecx, 8(%edi)
movl $output, %eax
popl %ebx
movl %ebp, %esp
popl %ebp
ret
|
/* externtest.cpp - An example of using assembly language functions with C++ */ #include <iostream> using namespace std; extern "C" { int square(int); float areafunc(int); char *cpuidfunc(void); } int main() { int radius = 10; int radsquare = square(radius); cout << "The radius squared is "<< radsquare << endl; float result; result = areafunc(radius); cout << "The area is " << result << endl; cout << "The CPUID is " << cpuidfunc() << endl; return 0; } |
$ as -o square.o square.s $ as -o areafunc.o areafunc.s $ as -o cpuidfunc.o cpuidfunc.s $ g++ -o externtest externtest.cpp square.o areafunc.o cpuidfunc.o $ ./externtest The radius squared is 100 The area is 314.159 The CPUID is GenuineIntel $ |