arm:c語言和彙編混合編程

僅做演示。html

1.C和彙編可相互調用,彙編子函數格式參考 彙編:普通的函數調用的彙編代碼解析 http://www.cnblogs.com/mylinux/p/4139972.htmllinux

  本文演示了 : 彙編嵌入到c語言;函數

            彙編調用c語言,c語言調用匯編。post

2.C函數參數從左到右是放到r0-r3,[不夠再push stack];push stack用stmfd ldmfd,右邊的參數會先入棧this

;//call_asm.s
    PRESERVE8
    AREA |C$$code|, CODE, READONLY
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    IMPORT cfunc_print
    IMPORT c_add
    IMPORT c_sub
    
    EXPORT AsmCallerAdd
    EXPORT AsmCallerSub
    EXPORT AsmCallerPrint
    EXPORT slib_ReadCpuStatus
    
AsmCallerAdd              ; ,執行子函數TestFunc6(1,2)
    sub r13, r13, #4    ;sp-=4 
    str r14, [r13]      ;sp--->lr
    bl c_add            ;BL : r0,r1中的參數傳到子函數
    ldr r14, [r13]      ;lr--->sp  
    add r13, r13, #4    ;sp+=4 
    bx r14              ;goto sp
    
AsmCallerSub 
    mov     ip, sp
    stmfd   sp!, {fp, ip, lr, pc}
    sub     fp, ip, #4
    bl      c_sub
    ldmfd   sp, {fp, sp, pc}  
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
AsmCallerPrint 
    sub r13, r13, #4    ;sp -= 4 
    str r14, [r13]      ;sp ---> lr
    bl cfunc_print      ; 
    ldr r14, [r13]      ;lr ---> sp  
    add r13, r13, #4    ;sp += 4 
    bx r14              ;goto sp
    
    
slib_ReadCpuStatus
    mov     ip, sp
    stmfd   sp!, {fp, ip, lr, pc}
    sub     fp, ip, #4
    mrs     r0,cpsr
    ldmfd   sp, {fp, sp, pc}
    
 
    
    END

 

//asm_c.c

/*
根據「ARM-thumb 過程調用標準」:
r0-r3    用做傳入函數參數,傳出函數返回值。在子程序調用之間,能夠將 r0-r3 用於任何用途。
         被調用函數在返回以前沒必要恢復 r0-r3。若是調用函數須要再次使用 r0-r3 的內容,則它必須保留這些內容。
r4-r11   被用來存放函數的局部變量。若是被調用函數使用了這些寄存器,它在返回以前必須恢復這些寄存器的值。
r12      是內部調用暫時寄存器 ip。它在過程連接膠合代碼(例如,交互操做膠合代碼)中用於此角色。
         在過程調用之間,能夠將它用於任何用途。被調用函數在返回以前沒必要恢復 r12。
r13      是棧指針 sp。它不能用於任何其它用途。sp 中存放的值在退出被調用函數時必須與進入時的值相同。
r14      是連接寄存器 lr。若是您保存了返回地址,則能夠在調用之間將 r14 用於其它用途,程序返回時要恢復
r15      是程序計數器 PC。它不能用於任何其它用途。
         注意:在中斷程序中,全部的寄存器都必須保護,編譯器會自動保護R4~R11
*/

int c_add(int a ,int b)
{
    return a+b;
}
int c_sub(int a ,int b)
{
    return a-b;
}

unsigned int asm_c_ctl_cp15(void)
{
    unsigned int i = 0;
    Uart_Printf("asm_c_ctl_cp15\n");
    
    __asm 
    {
        mrc p15,0,r0,c1,c0,0 
        MOV i,r0
    }
    return i;
}

unsigned int asm_c_ReadCPSR(void)
{
    unsigned int i = 0;
    __asm 
    {
        mrs     r0,cpsr
        MOV i,r0
    }
    return i;
}

void cfunc_print()
{
    Uart_Printf("this is cfunc_print,called_by_asm\n");
}
 
void asm_demo(void)
{
    int i, j,a ;
Uart_Printf("asm_demo\n");

asm_c_ctl_cp15();//在c中使用匯編語言操做協處理器cp15
Uart_Printf("4+5 = %d \n" , AsmCallerAdd(4, 5) ); //彙編調用c語言函數 //mdk_jlink: //get into AsmCallerAdd(4, 5) : r0=4 ,r1=5 //get into c_add : r0=4 ,r1=5 //return from c_add : r0=9 //return from AsmCallerAdd: r0=0x30006160 ,r1=9 . //函數參數從左到右是放到r0-r3,[不夠再push stack] //push stack用stmfd ldmfd,右邊的參數會先入棧 //STMFD&&LDMFD http://www.cnblogs.com/mylinux/p/4139972.html Uart_Printf("9-5 = %d \n" , AsmCallerSub(9, 5) );//彙編調用c語言函數
Uart_Printf(
"slib_ReadCPSR :%x \n" , asm_c_ReadCPSR() ); //在c語言中混合彙編,讀取Cpsr寄存器 AsmCallerPrint();//彙編調用c語言函數
switch(0x1f & slib_ReadCpuStatus()){//c語言調用匯編編寫的函數 case 0x13: Uart_Printf("in svc\n" , a); } } // asm_demo // asm_c_ctl_cp15 // 4+5 = 9 // 9-5 = 4 // slib_ReadCPSR :60000013 //mode[4-0] 10011 svc模式。 // this is cfunc_print,called_by_asm。 // in svc
相關文章
相關標籤/搜索