【发布时间】:2015-11-12 23:33:23
【问题描述】:
我有一个明天到期的作业,我需要在一个数组中找到浮点值的平均值。我似乎在书中或我的笔记中找不到任何相对有用的关于将整数转换为浮点数(ecx(数组长度)中的值 5 为 5.0,因此我可以在不截断的情况下进行除法)。
这是给我的代码,只有两行标记为 line1 和 line2 需要更改,但我似乎无法弄清楚它们需要更改为什么。关于如何完成这项工作的任何想法?
c++ 文件
#include <stdio.h>
extern"C"
{
float average(float [], int); // external assembly function prototypes
float max(float [], int);
float min(float [], int);
}
int main()
{
const int SIZE = 5;
float floatArr[SIZE] = {2.2, 3.75, 1.11, 5.9, 4.64};
printf("The array contains the float numbers: ");
for (int i = 0; i<SIZE; i++)
printf("%f ", floatArr[i]);
float val1 = average(floatArr, SIZE);
printf("\n\nThe average of the floats are: %f\n", val1);
float val2 = max(floatArr, SIZE);
printf("The largest float is: %f\n", val2);
float val3 = min(floatArr, SIZE);
printf("The smallest float is: %f\n", val3);
return 0;
}
asm 文件
.686
.model flat
.code
_average PROC
push ebp ; save the caller frame pointer
mov ebp, esp
mov ebx, [ebp+8] ; address of first element in array
mov ecx, [ebp+12] ; store size of array in ecx
xor edx, edx ; counter for loop
fldz ; set top of FPU stack to zero
loopAdd:
fld dword ptr[ebx+edx*4] ; load next array onto register stack at st(1)
faddp ; add st(0) to st(1) and pop register stack
inc edx ; increment counter
cmp ecx, edx ; compare size of array in ecx with counter in edx
jg loopAdd ; if ecx > edx jump to loopAdd and continue
line1 cvtsi2sd eax, xmm0 ;load array size as float to compute average
line2 fdivp ;divide st(0) by st(1) and pop register stack
pop ebp ; restore caller frame pointer
ret ; content of st(0) is returned
_average ENDP
END
【问题讨论】:
-
为什么要混合 x87 和 sse 指令?
-
作为 MASM 的新手,我认为这没有什么害处。我错了吗?你能花时间解释一下吗?
-
好吧,并不是不能完成,但是 xmm0 是一个与 st(0) 完全不同的寄存器,您似乎假设它们是相关的。要在 fpu 堆栈上加载整数,可以使用
fild之类的东西。 -
我同意@harold 和使用FILD。不要使用 SSE(SIMD 指令)。如果您在大部分工作中使用 x87 FPU,请坚持使用。您的 MASM 汇编器可能不接受像
cvtsi2sd eax, xmm0这样的 SIMD 指令的原因是因为它是旧版本,或者您需要.XMM指令以及.686 -
好的,那么我将如何使用 FILD? “菲尔德 eax”?
标签: arrays assembly x86 masm x87