我有这个示例。对于我的任务,我需要使用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中的文档(