float[] 数组的平均值(Intel 8086)
Average of float[] array (Intel 8086)
我正在尝试将我的 ANSI C 代码与 ASM(准确地说是 TASM)模块结合起来。
我决定选择经典任务 - 获取数组中数字的平均值,它几乎可以正常工作,它编译和链接成功,但最后它说平均值等于 -0(当它不等于 -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
代码内部。我会很感激你的想法!
在实地址模式下,指针不仅仅是一个偏移量。所以要获取第二个参数 float* 你需要:
lds bx, [bp+8] ;full pointer
您可能想要 push ds
/pop ds
。
第一个参数是双字吗?你可以试试:
fidiv WORD PTR [bp+4] ; sum/n
为什么你从不从 FP 堆栈中弹出任何东西?
您至少在 returning 之前缺少最后一个 fstp DWORD PTR [bp]
。分别在您的 ABI 希望将 return 值写入的任何位置。
目前你正在推送到 FP 堆栈,计算平均值,仅此而已。你泄露了一个寄存器,却从未看过结果。
我明白了。看来我在那里遇到了两个问题:
首先——寻址。
bx
寄存器应填写 [bp+6]
而不是 [bp+8]
.
这很明显,因为我的第一个 arg 是整数,2B 长,不是吗?
除此之外,@Sep Roland 对我的 fidiv
指示是正确的。
我的值甚至不是 DWORD,它只是 WORD,它解决了我所有的问题。
现在可以使用了,谢谢大家的宝贵时间。
我无法删除我的问题,所以我发布了我的答案,也许有一天它会有用。
我正在尝试将我的 ANSI C 代码与 ASM(准确地说是 TASM)模块结合起来。
我决定选择经典任务 - 获取数组中数字的平均值,它几乎可以正常工作,它编译和链接成功,但最后它说平均值等于 -0(当它不等于 -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
代码内部。我会很感激你的想法!
在实地址模式下,指针不仅仅是一个偏移量。所以要获取第二个参数 float* 你需要:
lds bx, [bp+8] ;full pointer
您可能想要 push ds
/pop ds
。
第一个参数是双字吗?你可以试试:
fidiv WORD PTR [bp+4] ; sum/n
为什么你从不从 FP 堆栈中弹出任何东西?
您至少在 returning 之前缺少最后一个 fstp DWORD PTR [bp]
。分别在您的 ABI 希望将 return 值写入的任何位置。
目前你正在推送到 FP 堆栈,计算平均值,仅此而已。你泄露了一个寄存器,却从未看过结果。
我明白了。看来我在那里遇到了两个问题:
首先——寻址。
bx
寄存器应填写[bp+6]
而不是[bp+8]
.
这很明显,因为我的第一个 arg 是整数,2B 长,不是吗?除此之外,@Sep Roland 对我的
fidiv
指示是正确的。
我的值甚至不是 DWORD,它只是 WORD,它解决了我所有的问题。
现在可以使用了,谢谢大家的宝贵时间。
我无法删除我的问题,所以我发布了我的答案,也许有一天它会有用。