float []数组的平均值(Intel 8086)

时间:2016-05-08 16:34:02

标签: c assembly x86-16 tasm

我试图将我的ANSI C代码与ASM(TASM精确)模块结合起来。
我决定选择经典任务 - 获取数组中数字的平均值,它几乎正常工作,它会成功编译和链接,但最后它表示平均值等于-0(当它没有时)。

我做错了什么?这是 .c 代码所需的部分:

#include <stdio.h>
extern float avg(int, float*);

int main()
{
  int n = 2;
  float tab[] = {2.0, 3.0};
  printf("%.3g\n", avg(n, tab));

  return 0;
}

.asm 程序:

avg PROC
    finit
    push BP
    mov BP, SP

    push bx
    mov cx, [bp+4]      ; no of elements
    mov bx, [bp+8]      ; address

    fldz ; zero
    jcxz avg_end ; if cx==0, end

    iter:
    fadd DWORD PTR [bx]
    add bx, 4
    loop iter

    fidiv DWORD PTR [bp+4] ; sum/n

    avg_end:
    pop bx
    pop BP
    ret
avg ENDP

我的程序内部还有一个外部功能,效果很好 唯一的问题必须是avg PROC代码。我很感激你的想法!

3 个答案:

答案 0 :(得分:3)

在实地址模式中,指针不仅仅是偏移量。因此,要获取第二个参数 float * ,您需要:

lds bx, [bp+8]      ;full pointer

您可能需要push ds / pop ds

第一个论点甚至是dword?你可以试试:

fidiv WORD PTR [bp+4] ; sum/n

答案 1 :(得分:1)

为什么你永远不会从FP堆栈弹出任何东西?

在返回之前,你至少错过了一个fstp DWORD PTR [bp]。您的ABI希望将返回值写入。

目前你正在推动FP堆栈,计算平均值,就是这样。你已经泄露了一个登记册,从未查看过结果。

答案 2 :(得分:0)

我明白了。看来我有两个问题:

  • 首先 - 解决问题 bx注册表应填充[bp+6]而不是[bp+8] 这很明显,因为我的第一个arg是整数,2B长,不是吗?

  • 除此之外, @Sep Roland 与我的fidiv指令相符。
    我的价值甚至不是DWORD,它只是WORD,它解决了我所有的问题。

现在有效,谢谢大家的时间。
我无法删除我的问题,所以我发布了我的答案,也许它有一天会有用。