新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > ARM之---在C語言中內嵌匯編語言

        ARM之---在C語言中內嵌匯編語言

        作者: 時間:2016-11-11 來源:網絡 收藏
        開發Arm程序的時候,大多數時候使用C/C++語言就可以了,但匯編語言在某些情況下能夠實現一些C語言無法實現的功能,這時候就要調用一些匯編語言的程序.我們需要大概了解一下在C語言中如何嵌入匯編語言.

        1.內嵌匯編語言的語法:

        本文引用地址:http://www.104case.com/article/201611/316885.htm

        __asm

        {

        指令[;指令]

        ......

        [指令]

        }

        2.舉例:使能/禁止IRQ中斷

        __inline void enable_IRQ(void)

        {

        int tmp;

        __asm//嵌入匯編代碼

        {

        MRStmp,CPSR//讀取CPSR的值

        BICtmp,tmp,#0x80//將IRQ中斷禁止位I清零,即允許IRQ中斷

        MSRCPSR_c,tmp//設置CPSR的值

        }

        }

        __inline void disable_IRQ(void)

        {

        int tmp;

        __asm

        {

        MRStmp,CPSR

        ORRtmp,tmp,#Ox80

        MSRCPSR_c,tmp

        }

        }

        3.舉例:字符串復制

        void my-strcpy(const char *src,char *dst)

        {

        int ch;

        __asm

        {

        loop:

        #ifndef __thumb

        LDRB ch,[src],#1

        STRB ch,[dst],#1

        #else

        LDRB ch,[src]

        ADDsrc,#1

        STRB ch,[dst]

        ADDdst,#1

        #endif

        CMP ch,#0

        BNE loop

        }

        }

        int main(void)

        {

        const char *a="Hello world!";

        char b[20];

        __asm

        {

        MOVR0,a

        MOVR1,b

        BL my_strcpy,{R0,R1}

        }

        return(0);

        }

        4.內嵌匯編的指令用法:

        .操作書: 內嵌的匯編指令中作為操作數的寄存器和常量可以是C表達式.這些表達式可以是char,short或int等類型,而且這些表達式都是作為無符號數進行操作的.若要有符號數,用戶需要自己處理與符號有關的操作.編譯器將會計算這些表達式的值,并為其分配寄存器.

        .物理寄存器:內嵌匯編中使用物理寄存器是有限制的:

        _ 不能直接向PC(程序計數器)寄存器中賦值,程序跳轉只能通過B或BL指令來實現.

        _ 使用物理寄存器的指令中,不要使用過于復雜的C表達式

        _ 盡可能少的使用物理寄存器

        .常量: 在內嵌匯編指令中,常量前面的"#"可以省略

        .標號: C程序中的標號可以被內嵌的匯編指令使用.但是只有指令B可以使用C程序中的標號,而指令BL則不能使用.

        .內存單元的分配:所有內存分配均由C編譯器完成,分配的內存單元通過變量供內嵌匯編器使用.內嵌匯編器不支持內嵌匯編程序中用于內存分配的偽指令.

        5.內嵌匯編注意事項:

        .必須小心使用物理寄存器,如R0~R3,IP,LR,CPSR中的標志位,避免發生沖突.

        例如:

        __asm

        {

        MOVR0,x

        ADDy,R0,x/y

        }

        改成下面代碼會比較妥當:

        __asm

        {

        MOV var,x

        ADD y,var,x/y

        }

        .不要使用寄存器代替變量.

        .使用內嵌匯編無需保存和恢復寄存器.事實上,除了CPSR,SPSR寄存器,對物理寄存器先讀后寫都會引起匯編報錯.

        .匯編語言中","號作為操作數分隔符.如果有C表達式作為操作數,若表達式中包含有",",則必須使用()將其規約為一個匯編操作數,例如:

        __asm
        {

        ADD x,y,(f(),z)//"f(),z"為帶有","的C表達式.

        }

        6.不同數據類型對應的匯編指令:

        unsigned charLDRB/STRB

        unsigned shortLDRH/STRH

        unsigned int LDR/STR

        char LDRSB/STRSB

        short LDRSH/STRSH

        7.訪問C程序的變量:

        AREAglobals,CODE,READONLY

        EXPORTasmsubroutine

        IMPORTglobalvar;聲明的外部變量

        asmsubroutine

        LDRR1,=blobalval

        LDRR0,[R1]

        ADDR0,R0,#1

        STRR0,[R1]

        MOVPC,LR

        END



        評論


        技術專區

        關閉
        主站蜘蛛池模板: 平武县| 湘阴县| 临城县| 儋州市| 贺州市| 梅河口市| 盐城市| 富顺县| 雅安市| 宁晋县| 醴陵市| 库车县| 布尔津县| 无极县| 曲阳县| 佛学| 共和县| 凉山| 阜康市| 昭通市| 鄄城县| 佳木斯市| 喀喇沁旗| 长白| 深圳市| 五台县| 尼玛县| 敦化市| 页游| 舞钢市| 噶尔县| 辽阳市| 芦山县| 乐亭县| 拜泉县| 夏津县| 合江县| 田阳县| 镇安县| 酉阳| 饶河县|