C++ 如何调用c++;来自gcc内联arm7程序集的成员函数

C++ 如何调用c++;来自gcc内联arm7程序集的成员函数,c++,gcc,assembly,arm,C++,Gcc,Assembly,Arm,我有下面一段在x86上工作的代码,我需要将其转换为gcc/arm7内联汇编 替换堆栈似乎很简单,只需将堆栈指针移到r15而不是esp,但我不知道如何调用函数,或者如何将实际变量放入arm汇编代码中 Object *c; unsigned long _stack = (unsigned long)c->stack + 65535; void (Object::*_run)() = &Object::_run; __asm { mov ecx, _this // store

我有下面一段在x86上工作的代码,我需要将其转换为gcc/arm7内联汇编

替换堆栈似乎很简单,只需将堆栈指针移到
r15
而不是
esp
,但我不知道如何调用函数,或者如何将实际变量放入arm汇编代码中

Object *c;

unsigned long _stack = (unsigned long)c->stack + 65535;
void (Object::*_run)() = &Object::_run;

__asm
{
    mov ecx, _this // store pointer to this Object
    mov edx, _run  // store address of _run() function
    mov esp, stack // replace stack pointer with Object's internal stack
    call edx       // call the _run() function
}

编辑:

到目前为止,我有:

unsigned long _stack = (unsigned long)c->stack + 65535;
void (Object::*_run)() = &Object::_run;

asm volatile("mov %[__this], %r0\n\t"
             "mov %[__run], %r5\n\t"
             "mov %[__stack], %%sp\n\t"
             "blx %r5\n\t"
             : /* no output operands */
             : [__stack] "r" (_stack), 
               [__this] "r" (_this), 
               [__run] "r" (_run)
             : /* no clobbers */);
问:在x86 asm中,使用此调用约定,“this”指针进入ecx。 手臂伸向哪里

编辑:

A:

编辑:

我要做的就是在这里全面实施:


它在VisualStudio中工作得非常好,但我无法让它在XCode/iOS中正常工作。虽然它使用x86汇编,但同样适用于arm汇编。虽然它使用x86汇编,但同样适用于arm汇编。

指定寄存器
r0
r3
用于参数传递。
this
指针始终位于第一个寄存器中,这将是
r0

指定寄存器
r0
r3
用于参数传递。
这个
指针总是在第一个寄存器中,这将是
r0

我不太确定你在那里用堆栈指针做什么-这是ARM上不需要的x86习惯用法,还是你有意要设置一个新的堆栈指针

在任何情况下,堆栈指针位于
r13
-程序计数器位于
r15
-
LDR
MOV
进入
PC
影响分支。在函数序言之外,SP已经指向堆栈上的下一个位置,因此,如果由于寄存器
r0-r3
不足而需要在堆栈上传递参数,则只需修改它—这里的情况并非如此

如果确实修改了堆栈指针,则需要在函数调用后将其还原,否则在函数退出时会出现一个很好的小崩溃

最后,您需要将ARM[E]ABI允许被调用方在函数调用时修改的所有寄存器声明为clobbered。这是
r0-r3
r9
{maybe}和
r12


如果你在iOS上这么做,ISTR寄存器的使用会有细微的变化

我不太清楚您在那里使用堆栈指针做什么-这是一种在ARM上不需要的x86习惯用法,还是您有意尝试设置一个新的堆栈指针

在任何情况下,堆栈指针位于
r13
-程序计数器位于
r15
-
LDR
MOV
进入
PC
影响分支。在函数序言之外,SP已经指向堆栈上的下一个位置,因此,如果由于寄存器
r0-r3
不足而需要在堆栈上传递参数,则只需修改它—这里的情况并非如此

如果确实修改了堆栈指针,则需要在函数调用后将其还原,否则在函数退出时会出现一个很好的小崩溃

最后,您需要将ARM[E]ABI允许被调用方在函数调用时修改的所有寄存器声明为clobbered。这是
r0-r3
r9
{maybe}和
r12


如果你在iOS上这么做,ISTR寄存器的使用会有细微的变化

> P>容易获得ABI所需信息(如寄存器在哪些值中传递):只需写几行虚线代码,调用C++方法,并将结果拆解(在目标平台上)。只需写几行虚线,其中调用C++方法,并将结果拆解(在目标平台上)。

,对于GCC内嵌汇编程序来说,<代码> >调用< /代码>不是特别安全,因为没有办法告诉编译器关于它(没有限制GCC内联ASM指令可以表示)。“这个东西包含一个函数调用,请执行所有必要的操作来保存/恢复寄存器中保存的任何内容,这些内容在进行函数调用时可能会更改”)

理论上,您可以通过提供一个clobber列表来“手动”实现这一点,该列表指定根据平台ABI进行函数调用时可能更改的所有寄存器(在ARM上有很多,我认为几乎所有寄存器都不包括
sp
…)。但这样做通常会造成gcc告诉您无法满足约束的情况(即,它没有任何寄存器可以将“需要保留的内容”填充到其中),具体取决于使用内联asm的上下文

为什么您需要从内联程序集中调用函数?难道您不能使用
静态内联
函数,将普通C代码(执行函数调用)与内联程序集中结合起来,来完成只能在内联程序集中完成的任务吗


如果整个函数仅为内联汇编,那么ARM上的gcc提供了一种解决方法-即
\uuuuu属性(裸的))
选项。它告诉编译器不要为它创建函数序言/尾声,您有义务自己编写这些,即添加保存/恢复此函数使用但由EABI声明保留的寄存器的代码。通过“外包”将函数调用到
静态内联\u属性的内联程序集__((裸体))
function,您可以避免必须指定大量的clobber列表,因为编译器会识别出这是一个函数调用(并根据需要保留/还原它,即使在内联代码时也是如此)