【发布时间】:2014-06-19 08:06:57
【问题描述】:
[作业]:尝试完全按照 C 代码所说的去做。
C版完整功能代码注释:
/*
double f(double x)
{
return x * 2.0;
}
double foo (int a[], double b[], int n)
{
int *pint;
double *pdouble;
double sum = 0.0;
for (pint = a, pdouble = b; n-- ; pint++, pdouble++)
{
*pdouble = f((double)*pint);
sum += *pdouble;
}
return sum;
}
*/
.text
.globl f
f:
pushl %ebp
movl %esp, %ebp
pushl %ebx
/*fldl 8(%ebp)
fstpl 8(%ebp)*/
/*movl 8(%ebp), %ebx*/
shll $2, 8(%ebp)
fldl 8(%ebp)
popl %ebx
movl %ebp, %esp
popl %ebp
ret
.globl foo
foo:
pushl %ebp
movl %esp, %ebp
pushl %ebx
pushl %esi
subl $16, %esp /* for the local variables */
fldz /* 0 to the top of the FPU's stack */
fstpl (%esp) /* double sum = 0 */
movl 8(%ebp), %ebx /* > pint */
movl %ebx, -4(%ebp) /* = a < | INIT */
movl 12(%ebp), %esi /* > pdouble */
movl %esi, -8(%ebp) /* = b < | INIT */
L1: cmpl $0, 16(%ebp)
js outfor
pushl %eax
pushl %ecx
pushl %edx
movl -4(%ebp), %edi
fildl (%edi) /* *pint to the top of FPU'S stack */
subl $8, %esp /* > pushdouble */
fstpl (%esp) /* *pint < */
call f /* f((double)*pint) to the top of FPU'S stack */
addl $8, %esp /* clears double pint from stack */
popl %edx
popl %ecx
popl %eax
movl -8(%ebp), %eax
fldl (%eax) /* *pdouble to the top of FPU's stack */
faddl -16(%ebp) /* sum += *pdouble (stored in FPU'S stack) */
fstpl -16(%ebp) /* sum += *pdouble (stored in sum) */
decl 16(%ebp)
addl $4, -4(%ebp)
addl $8, -8(%ebp)
jmp L1
outfor: fldl -16(%ebp)
popl %esi
popl %ebx
movl %ebp, %esp
popl %ebp
foo 将同时调用f。我的问题就在那里。我如何告诉编译器以double 威胁x?我最好的选择fldl 8(%ebp) fstpl 8(%ebp) 是给我糟糕的数字。显然,任何其他后缀 l 的指令都将其威胁为 4 字节长。
然后,一旦我对x 进行了正确解释,如何在不使用局部变量的情况下将 if 乘以 2.0(读得好,不是整数)?我尝试使用shll,但似乎不存在double 值的转变。我也不能fldl $2。
【问题讨论】:
-
要乘以 2,您可以将值添加到自身。
-
这么想,但根本不会是双倍的,对不起小姐,这是一个家庭作业。
-
fld1也是如此,将其添加到自身并将结果乘以参数。 -
起初我以为你在做一些基于体积的计算!
pint和pdouble不是很有帮助的名字。 -
假设我必须将它乘以 50.0 或 500.0 或 65363.0,那会怎样?仍然需要正确的
xanyways。
标签: c assembly double bit-shift att