从C中调用X86组件中的nasm浮动



我有这个示例。对于我的任务,我需要使用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: %fn", my_pow(base, exp));
  return 0;
}

使用NASM和GCC构建:

nasm -f macho64 calc.asm
gcc -m64 -o main main.c calc.o

作为输出,我得到了:

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中返回浮点返回值。

所以彼得所说的是,C符合者会将您提供的参数放在这些寄存器中(因为这是您使用的原型 呼叫约定需要它的原型(。由于您没有在代码中对它们进行操作,因此最终会在XMM0中使用base参数。这意味着您的base参数2.0被返回C作为返回值。

在线查找" movss"one_answers" muls"之类的说明,这些是您需要知道的那种说明。(链接到x86 tag Wiki中的文档(

最新更新