0

我想将指针传递给 C 和 ASM 代码之间的数组。我有一个包含四个双精度值的数组,我需要将它们传递给 asm,将它们加载到 xmm,相乘并将指向四个值的指针返回给 C。将数据加载到 xmm0 时出现错误。

如何将此指针传递给 ASM 并返回给 C ?如何将所有四个数字加载到 xmm0 ?

这是代码:

.text

.globl calkasse
.type calkasse, @function

calkasse:   
pushq %rbp
movq %rsp, %rbp

movq 8(%rbp), %rax
movaps 16(%rax), %xmm0
mulps %xmm0,%xmm0

movq  %rbp,   %rsp
popq   %rbp
ret

和C代码:

double (*calkasse(double (*)[4]))[4];

int main(void) {

double suma=0.0;
double poczatek=1.0;
double koniec=5.0;
double step=0.001;
double i=poczatek;
double array[4];
double (*wynik)[4];

    array[0] = i;
    array[1] = i+step;
    array[2] = i+(2*step);
    array[3] = i+(3*step);
    wynik = calkasse(&array);
    suma+=*wynik[0]+*wynik[1]+*wynik[2]+*wynik[3];
return 1;
}
4

2 回答 2

0

您需要将项目编译为程序集文件,然后进行这些更改。如果您使用内联汇编,那么会发生 TON(我的意思是我在测试中看到的大量)在您的 C 代码和内联汇编之间对系统进行了更改。基本上,它会破坏您在进入装配部分之前看到的系统状态。原因很明显,因为您的 C 代码将不得不使用 C 库来弄清楚内联汇编的含义。因此,您的持久性将在此期间被破坏,并且值将被推送和弹出。

为了在进入程序集之前不破坏寄存器,您可以尝试在创建程序集后将程序集添加到目标文件中。您可以在开始添加代码之前使用 GDB 找出代码在做什么,并且您应该能够手动获取您要查找的地址,然后您可以将其放入变量中。我会把它放在一个变量中,因为如果你把它插入一个寄存器,你必须在添加代码之后跟踪程序集,以确保你在正确的时间把它放在正确的寄存器中。如果将其放置为变量,则可以使用 mov 指令(或 leal IIRC)将指针值放入变量中,然后在 C 代码中,您可以将此变量设置为 null。然后,您可以在实际手动编写程序集之前编写您的 C 代码(基本上该变量是一个模拟)。希望这可以帮助,

于 2013-05-30T20:13:22.260 回答
0

您必须使编译器的行为可预测。AC 函数可以通过多种方式编译。它还依赖于操作系统和平台。因此,例如,允许通过寄存器/寄存器优化/操作系统禁止寄存器传递函数参数......这些将改变编译。尝试编写一个关闭优化的函数,并查看编译器的汇编输出。这样,您将拥有一个受控制的编译案例,该案例至少在一个操作系统和平台上是一致的......然后您可以将您的内联程序集添加到该函数中。始终关注装配输出......这需要中等逆向工程。

于 2013-05-31T18:16:56.660 回答