我想将指针传递给C和ASM代码之间的数组。我有一个四个double值的数组,我需要将它们传递给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;
}
答案 0 :(得分:0)
您需要将项目编译为程序集文件,然后进行这些更改。如果你使用内联汇编,会发生的事情是你的C代码和内联汇编之间的系统更改有一个TON(我的意思是我在测试中看到的吨数)。基本上,它会在进入装配部分之前破坏系统的状态。很明显,为什么这是因为你的C代码必须使用C库甚至弄清楚内联汇编的含义。因此,在此期间您的持久性将被销毁,并且将推送和弹出值。
要在进入程序集之前不销毁寄存器,可以尝试在创建后在目标文件中添加程序集。您可以使用GDB在开始添加代码之前弄清楚代码的作用,并且您应该能够手动获取您正在寻找的地址,然后您可以将其放在变量中。我会将它放在一个变量中,因为如果将它插入寄存器,则必须在添加代码后跟踪程序集,以确保在正确的时间将其放入正确的寄存器中。如果将变量放在变量上,可以使用mov指令(或leal IIRC)将指针值放入变量中,然后在C代码中,只需将此变量设置为null即可。然后,您可以在实际手动编写程序集之前编写C代码(基本上变量是模拟)。希望这会有所帮助,祝你好运。
答案 1 :(得分:0)
您必须使编译器具有可预测性。可以通过多种方式编译C函数。它还取决于操作系统和平台。因此,例如,允许函数参数通过寄存器/寄存器优化/ os禁止寄存器...这些将改变编译。尝试编写一个关闭优化的函数,然后查看编译器的汇编输出。这样你将有一个更多受控的编译案例,至少在一个操作系统和平台上是一致的...然后你可以将你的内联汇编添加到该函数中。始终关注装配输出......这需要中等逆向工程。