最近在玩E2手机,想把C/Invoke(http://www.nongnu.org/cinvoke/)移植到E2上,它的CPU是arm的,系统是Linux,下了源代码,按照说明自已添了一个gcc_arm_linux的arch文件,可是在修改时发现里边还有asm代码,以前没弄过,开始完全看不懂,于是呼!在网上找来《ARM指令集》找到要用到的指令,指令到是简单,可是asm内嵌c的写法把我搞晕了,又找来《AT&T ASM参考》,这才把代码中的几个内嵌ARM汇编的宏对付上。部分代码:
/////////////////////////////////////
// macros
/////////////////////////////////////
// the following examples are given
// for x86 in MASM syntax. Some of these
// macros might not need to be implemented
// in inline assembly, depending on the arch,
// but likely most of them will.
// this macro stores the values in the input
// registers in the ArchRegParms structure passed as 'regparms'.
// In the example below we store ecx and edx because
// they are used in the fastcall convention to pass
// parameters.
// 存储“输入寄存器”中的值到regparms中。
#define ARCH_SAVE_REGPARMS(regparms)
__asm__("str %%r0, %0;
str %%r1, %1;
str %%r2, %2;
str %%r3, %3;
str %%r4, %4;
str %%r5, %5;
str %%r6, %6;
str %%r7, %7;" :
"=m" ((regparms).a1),
"=m" ((regparms).a2),
"=m" ((regparms).a3),
"=m" ((regparms).a4),
"=m" ((regparms).d0),
"=m" ((regparms).d1),
"=m" ((regparms).d2),
"=m" ((regparms).d3) :: );
// this macro does two things: copies the values
// stored in regparms into the input registers,
// and calls the function pointed to by the pointer
// ep.
// 复制regparms中的值到“输入寄存器”中,并调用指针ep指向的函数。
#define ARCH_CALL(regparms, ep)
__asm__("ldr %%r0, %0;
ldr %%r1, %1;
ldr %%r2, %2;
ldr %%r3, %3;
ldr %%r4, %4;
ldr %%r5, %5;
ldr %%r6, %6;
ldr %%r7, %7;
ldr %%r8, %8;
bx %%r8;" ::
"m" ((regparms).a1),
"m" ((regparms).a2),
"m" ((regparms).a3),
"m" ((regparms).a4),
"m" ((regparms).d0),
"m" ((regparms).d1),
"m" ((regparms).d2),
"m" ((regparms).d3),
"m" (ep) :
"r0",
"r1",
"r2",
"r3",
"r4",
"r5",
"r6",
"r7",
"r8");
// saves any possible return values in the ArchRetValue
// structure given by archvalue.
// 保存archvalue中任何可能的返回值。
#define ARCH_SAVE_RETURN(archvalue, type)
__asm__("str %%r0, %0;
str %%r1, %1;
str %%r4, %2;" :
"=m" ((archvalue).a1),
"=m" ((archvalue).a2),
"=m" ((archvalue).d0) :: );
// stores the return values in the ArchRetValue structure
// into any place where a caller might expect to find them
// 存储archvalue中的值到“调用者”能找到的地方(寄存器)。
#define ARCH_SET_RETURN(archvalue, type)
__asm__("ldr %%r0, %0;
ldr %%r1, %1;
ldr %%r4, %2;" ::
"m" ((archvalue).a1),
"m" ((archvalue).a2),
"m" ((archvalue).d0) :
"r0",
"r1",
"r4");
// increases the stack size by bcount bytes
#define ARCH_PUT_STACK_BYTES(bcount)
__asm__("ldr %%r8, %0;
sub %%sp, %%sp, %%r8;" ::
"m" (bcount) :
"r8",
"sp");
// decreases the stack size by bcount bytes
#define ARCH_REMOVE_STACK_BYTES(bcount)
__asm__("ldr %%r8, %0;
add %%sp, %%sp, %%r8;" ::
"m" (bcount) :
"r8",
"sp");
// copies the current stack pointer into the pointer variable
// stackp
#define ARCH_GET_STACK(stackp)
__asm__("str %%r13, %0;" : "=m" (stackp) :: );
// copies the current frame pointer into the pointer variable
// framep
#define ARCH_GET_FRAME_PTR(framep)
__asm__("str %%r11, %0;" : "=m" (framep) :: );
『本文转载自网络,版权归原作者所有,如有侵权请联系删除』