我试图将我的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
代码。我很感激你的想法!
答案 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,它解决了我所有的问题。
现在有效,谢谢大家的时间。
我无法删除我的问题,所以我发布了我的答案,也许它有一天会有用。