ARM C内嵌asm写法

   最近在玩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) :: );

主要说一下AT&T ASM内嵌的写法,格式如下:
__asm__("指令" : "操作约束 (输出参数) : (输入参数) : 寄存器约束 );

指令:
当然就是ARM的汇编指令了,但要注意的是寄存器要用%%来约束,以防与参数%冲突。
操作约束(
OperationConstraint) 我个人理解为参数传递方式,如:"=m",中“=”表示输出,还可以不写表示输入,"+"表示输 入和输出, “m”表示使用内存,在x86中,还可以是“a”、“b”、“c”等,表示使用什么样的寄存器。
输出参数:对应C代码中变量,通过是由汇编代码从寄存器或内存中取出来的值,以便在C代码中使用。多个参数时,用逗号分  隔。
输入参数:C代码向汇编代码输入的参数。
寄存器约束(Register Constraint): 个人感觉是给“编译器”看的,帮你检查代码,防止你修改了不该改的寄存器的内容。

   在ARM中,寄存器与X86上的不同,没ax、bx什么的,它是r0~r15,其中还包括几个特殊用途的寄存器,如:r11=fp(帧指针)、r13=sp(堆栈指针)等。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值