Assembly 从C调用x86程序集中的NASM浮点
我有这个。对于我的任务,我需要使用Assembly 从C调用x86程序集中的NASM浮点,assembly,x86,x86-64,Assembly,X86,X86 64,我有这个。对于我的任务,我需要使用float而不是int: #include <stdio.h> extern float my_pow(float base, float exp); int main(int argc, char const *argv[]) { float base = 2.0, exp = 8.0; printf("Result: %f\n", my_pow(base, exp)); return 0; } 作为输出,我得到以下结果: Res
float
而不是int
:
#include <stdio.h>
extern float my_pow(float base, float exp);
int main(int argc, char const *argv[]) {
float base = 2.0, exp = 8.0;
printf("Result: %f\n", my_pow(base, exp));
return 0;
}
作为输出,我得到以下结果:
Result: 2.000000
当我的结果应该是256.0
时。
我做错了什么
更新:
我的asm代码没有更改
global _my_pow
section .text
_my_pow:
push rbp ; create stack frame
mov rbp, rsp
cmp edi, 0 ; Check if base is negative
mov eax, 0 ; and return 0 if so
jl end
mov eax, edi ; grab the "base" argument
mov edx, esi ; grab the "exponent" argument
multiply:
imul eax, edi ; eax * base
sub esi, 1 ; exponent - 1
cmp esi, 1 ; Loop if exponent > 1
jg multiply
end:
pop rbp ; restore the base pointer
ret ; return from procedure
我想详述彼得的答案,因为初学者可能不太清楚他在说什么 在_my_pow下的第一部分代码中,您可以从edi和esi获得前两个参数,这对于大多数x86_64函数都是正确的。但是它与浮点数不同。处理浮点数时,第一个参数在寄存器xmm0中,第二个参数在xmm1中。浮点返回值在xmm0中返回 Peter所说的是C编译器将把您提供的参数放入这些寄存器中(因为您使用的原型+调用约定要求它这样做)。由于您在代码中没有对它们进行操作,因此最后在xmm0中使用
base
参数。这意味着您的base
参数2.0将作为返回值返回给C
在网上查找“movss”和“mulss”等说明,这些是您需要知道的正确操作说明。(链接到文档)我想进一步阐述彼得的答案,因为初学者可能不太清楚他在说什么 在_my_pow下的第一部分代码中,您可以从edi和esi获得前两个参数,这对于大多数x86_64函数都是正确的。但是它与浮点数不同。处理浮点数时,第一个参数在寄存器xmm0中,第二个参数在xmm1中。浮点返回值在xmm0中返回 Peter所说的是C编译器将把您提供的参数放入这些寄存器中(因为您使用的原型+调用约定要求它这样做)。由于您在代码中没有对它们进行操作,因此最后在xmm0中使用
base
参数。这意味着您的base
参数2.0将作为返回值返回给C
在网上查找“movss”和“mulss”等说明,这些是您需要知道的正确操作说明。(指向文档的链接)您忘记显示程序集代码。该链接中的
\u my\u pow
使用整数参数和返回值。如果您告诉C编译器它接受并返回float
,您将得到返回值=first arg,因为它不接触xmm0
。如果您查看编译器生成的asm,或者使用调试器逐步完成它,您可以看到这一点。如何为浮点数重写此asm代码?您需要使用浮点指令,x87或SSE。您可以显示示例吗?您忘记显示汇编代码。该链接中的\u my\u pow
使用整数参数和返回值。如果您告诉C编译器它接受并返回float
,您将得到返回值=first arg,因为它不接触xmm0
。如果您查看编译器生成的asm,或者使用调试器逐步完成它,您会看到这一点。如何为浮点数重写此asm代码?您将需要使用浮点指令,x87或SSE。您可以演示示例吗?
global _my_pow
section .text
_my_pow:
push rbp ; create stack frame
mov rbp, rsp
cmp edi, 0 ; Check if base is negative
mov eax, 0 ; and return 0 if so
jl end
mov eax, edi ; grab the "base" argument
mov edx, esi ; grab the "exponent" argument
multiply:
imul eax, edi ; eax * base
sub esi, 1 ; exponent - 1
cmp esi, 1 ; Loop if exponent > 1
jg multiply
end:
pop rbp ; restore the base pointer
ret ; return from procedure