Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 从C调用x86程序集中的NASM浮点_Assembly_X86_X86 64 - Fatal编程技术网

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