gpt4 book ai didi

c - 内联汇编中的 double 字(GCC、IA-32)

转载 作者:行者123 更新时间:2023-11-30 18:09:24 25 4
gpt4 key购买 nike

我刚刚开始学习汇编,我想使用指定的舍入模式对浮点值进行舍入。我尝试使用 fstcwfldcwfrndint 来实现这一点。

现在我遇到了一些错误:

~ $ gc a02p
gcc -Wall -g a02p.c -o a02p
a02p.c: In function `roundD':
a02p.c:33: error: parse error before '[' token
a02p.c:21: warning: unused variable `mode'
~ $

我不确定我这样做是否正确。我不想使用任何预定义的函数。我想使用 GCC 内联汇编。

这是代码:

#include <stdio.h>
#include <stdlib.h>

#define PRECISION 3
#define RND_CTL_BIT_SHIFT 10

// floating point rounding modes: IA-32 Manual, Vol. 1, p. 4-20
typedef enum {
ROUND_NEAREST_EVEN = 0 << RND_CTL_BIT_SHIFT,
ROUND_MINUS_INF = 1 << RND_CTL_BIT_SHIFT,
ROUND_PLUS_INF = 2 << RND_CTL_BIT_SHIFT,
ROUND_TOWARD_ZERO = 3 << RND_CTL_BIT_SHIFT
} RoundingMode;

double roundD (double n, RoundingMode roundingMode)
{

short c;
short mode = (( c & 0xf3ff) | (roundingMode));


asm("fldcw %[nIn] \n"
"fstcw %%eax \n" // not sure why i would need to store the CW
"fldcw %[modeIn] \n"
"frndint \n"
"fistp %[nOut] \n"


: [nOut] "=m" (n)
: [nIn] "m" (n)
: [modeIn] "m" (mode)

);

return n;


}

int main (int argc, char **argv)
{
double n = 0.0;


if (argc > 1)
n = atof(argv[1]);

printf("roundD even %.*f = %.*f\n",
PRECISION, n, PRECISION, roundD(n, ROUND_NEAREST_EVEN));
printf("roundD down %.*f = %.*f\n",
PRECISION, n, PRECISION, roundD(n, ROUND_MINUS_INF));
printf("roundD up %.*f = %.*f\n",
PRECISION, n, PRECISION, roundD(n, ROUND_PLUS_INF));
printf("roundD zero %.*f = %.*f\n",
PRECISION, n, PRECISION, roundD(n, ROUND_TOWARD_ZERO));

return 0;
}

我离做对了吗?

最佳答案

更好的过程是编写一个对浮点值进行舍入的简单函数。接下来,指示编译器打印该函数的汇编列表。您可能希望将该函数放在单独的文件中。

此过程将向您展示编译器使用的调用和退出约定。通过将该函数放置在单独的文件中,您无需构建其他文件。此外,它还使您有机会用汇编语言函数替换 C 语言函数。

虽然支持内联汇编,但我更喜欢用汇编语言替换整个函数,而不是使用内联汇编(内联汇编不可移植,因此移植到不同平台时必须更改源代码)。

关于c - 内联汇编中的 double 字(GCC、IA-32),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2304765/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com