【发布时间】:2010-02-12 05:47:32
【问题描述】:
我刚开始在我的计算机科学课上学习汇编,我有一个任务是使用指定的舍入模式对浮点值进行舍入。我尝试使用fstcw、fldcw 和frndint 来实现这一点。我修改了舍入控制位,将数字四舍五入,然后恢复之前的控制位(赋值的要求)。
当前突出的问题是指令fld %1似乎将错误的值加载到st(0)浮点寄存器中(例如,如果我调用值为2.6207的函数,则数字-1.9427(。 ..)e-29 被加载到寄存器中)。这可能是由于滥用了gcc 的内联asm() 或其他原因,但我不确定为什么会发生这种情况。
这是我所拥有的:
double roundD (double n, RoundingMode roundingMode)
{
// control word storage (2 bytes for previous, 2 for current)
char *cw = malloc(4*sizeof(char));
char *cw2 = cw + 2;
asm("fstcw %3;" // store control word in cw
"mov %3,%4;" // copy control word into cw2
"and $0xF3FF,%4;" // zero out rounding control bits
"or %2,%4;" // put new mode into rounding control bits
"fldcw %5;" // load the modified control word
"fld %1;" // load n into st(0)
"frndint;" // round n
"fstp %0;" // load st(0) back into n
"fldcw %3;" // load the old control word from cw
: "=m" (n)
: "m" (n), "m" (roundingMode),
"m" (cw), "r" (cw2), "m" (cw2) // mov requires one argument in a register
);
free(cw);
return n;
}
如果您能指出该代码有什么问题,特别是与 fld %1 行和 asm 输入/输出相关的任何指针,我将不胜感激。 (当然,如果您发现其他问题,也请随时告诉我。)我不希望任何人为我做功课,只要指出我正确的方向即可。谢谢!
【问题讨论】:
-
你能告诉我们这个函数的汇编输出吗?如果不是太麻烦的话,还有代码字节。
-
@John:将要组装的代码并不奇怪;这一切都在一个巨大的不透明(对 gcc)asm 块中。 :-P 然而,将其拆分为许多小的 asm 语句(如我的帖子)会给 gcc 更多的空间来做不同的事情。
-
不清楚究竟将使用哪些代码字节,因为寻址模式似乎都是隐含的,而不是明确说明的。这个问题很可能是寻址问题而不是指令选择问题。