當前位置:首頁 » 編程軟體 » arm編譯c

arm編譯c

發布時間: 2023-06-19 11:51:34

⑴ arm編程c語言中嵌入匯編實現1+2+3+...+100

C語言中static關鍵字的常見用法及舉例

在嵌入式系統開發中,目前使用的主要編程語言是C和匯編,

C++已經有相應的編譯器,但是現在使用還是比較少的。在稍大

規模的嵌入式軟體中,例如含有OS,大部分的代碼都是用C編

寫的,主要是因為C語言的結構比較好,便於人的理解,而且有

大量的支持庫。盡管如此,很多地方還是要用到匯編語言,例如

開機時硬體系統的初始化,包括CPU狀態的設定,中斷的使能,

主頻的設定,以及RAM的控制參數及初始化,一些中斷處理方

面也可能涉及匯編。另外一個使用匯編的地方就是一些對性能非

常敏感的代碼塊,這是不能依靠C編譯器的生成代碼,而要手工

編寫匯編,達到優化的目的。而且,匯編語言是和CPU的指令集

緊密相連的,作為涉及底層的嵌入式系統開發,熟練對應匯編語

言的使用也是必須的。

單純的C或者匯編編程請參考相關的書籍或者手冊,這里主要討

論C和匯編的混合編程,包括相互之間的函數調用。下面分四種

情況來進行討論,暫不涉及C++。

1. 在C語言中內嵌匯編

在C中內嵌的匯編指令包含大部分的ARM和Thumb指令,不過其

使用與匯編文件中的指令有些不同,存在一些限制,主要有下面

幾個方面:

a. 不能直接向PC寄存器賦值,程序跳轉要使用B或者BL指令

b. 在使用物理寄存器時,不要使用過於復雜的C表達式,避免物理寄存器沖突

c.
R12和R13可能被編譯器用來存放中間編譯結果,計算表達式值時可能將R0到R3、R12及R14用於子程序調用,因此要避免直接使用這些物理寄存器

d. 一般不要直接指定物理寄存器,而讓編譯器進行分配

內嵌匯編使用的標記是 __asm或者asm關鍵字,用法如下:

__asm

{

instruction [; instruction]



[instruction]

}

asm(「instruction [; instruction]」);

下面通過一個例子來說明如何在C中內嵌匯編語言,

#include

void my_strcpy(const char *src, char *dest)

{

char ch;

__asm

{

loop:

ldrb ch, [src], #1

strb ch, [dest], #1

cmp ch, #0

bne loop

}

}

int main()

{

char *a = "forget it and move on!";

char b[64];

my_strcpy(a, b);

printf("original: %s", a);

printf("ed: %s", b);

return 0;

}

在這里C和匯編之間的值傳遞是用C的指針來實現的,因為指針

對應的是地址,所以匯編中也可以訪問

2. 在匯編中使用C定義的全局變數

內嵌匯編不用單獨編輯匯編語言文件,比較簡潔,但是有諸多限

制,當匯編的代碼較多時一般放在單獨的匯編文件中。這時就需

要在匯編和C之間進行一些數據的傳遞,最簡便的辦法就是使用

全局變數。

/* cfile.c

* 定義全局變數,並作為主調程序

*/

#include

int gVar_1 = 12;

extern asmDouble(void);

int main()

{

printf("original value of gVar_1 is: %d", gVar_1);

asmDouble();

printf(" modified value of gVar_1 is: %d", gVar_1);

return 0;

}

對應的匯編語言文件

;called by main(in C),to double an integer, a global var defined in C

is used.

AREA asmfile, CODE, READONLY

EXPORT asmDouble

IMPORT gVar_1

asmDouble

ldr r0, =gVar_1

ldr r1, [r0]

mov r2, #2

mul r3, r1, r2

str r3, [r0]

mov pc, lr

END

3. 在C中調用匯編的函數

在C中調用匯編文件中的函數,要做的主要工作有兩個,一是在

C中聲明函數原型,並加extern關鍵字;二是在匯編中用

EXPORT導出函數名,並用該函數名作為匯編代碼段的標識,最

後用mov pc, lr返回。然後,就可以在C中使用該函數了。從

C的角度,並不知道該函數的實現是用C還是匯編。更深的原因

是因為C的函數名起到表明函數代碼起始地址的左右,這個和匯

編的label是一致的。

/* cfile.c

* in C,call an asm function, asm_strcpy

* Sep 9, 2004

*/

#include

extern void asm_strcpy(const char *src, char *dest);

int main()

{

const char *s = "seasons in the sun";

char d[32];

asm_strcpy(s, d);

printf("source: %s", s);

printf(" destination: %s",d);

return 0;

}

;asm function implementation

AREA asmfile, CODE, READONLY

EXPORT asm_strcpy

asm_strcpy

loop

ldrb r4, [r0], #1 ;address increment after read

cmp r4, #0

beq over

strb r4, [r1], #1

b loop

over

mov pc, lr

END

在這里,C和匯編之間的參數傳遞是通過ATPCS(ARM

Thumb Procere Call Standard)的規定來進行的。簡單的說就

是如果函數有不多於四個參數,對應的用R0-R3來進行傳遞,多

於4個時藉助棧,函數的返回值通過R0來返回。

4. 在匯編中調用C的函數

在匯編中調用C的函數,需要在匯編中IMPORT 對應的C函數名

,然後將C的代碼放在一個獨立的C文件中進行編譯,剩下的工

作由連接器來處理。

;the details of parameters transfer comes from ATPCS

;if there are more than 4 args, stack will be used

EXPORT asmfile

AREA asmfile, CODE, READONLY

IMPORT cFun

ENTRY

mov r0, #11

mov r1, #22

mov r2, #33

BL cFun

END

/*C file, called by asmfile */

int cFun(int a, int b, int c)

{

return a + b + c;

}

在匯編中調用C的函數,參數的傳遞也是通過ATPCS來實現

的。需要指出的是當函數的參數個數大於4時,要藉助stack,具

體見ATPCS規范

⑵ 8.應用C語言進行ARM 系統軟體開發時從預處理、編譯、匯編到鏈接,編譯系統要做哪些工作,生成哪些文件

預編譯將.c
文件轉化成
.i文件使用的gcc命令是:gcc
–E對應於預處理命令cpp編譯將.c/.h文件轉換成.s文件使用的gcc命令是:gcc
–S對應於編譯命令
cc
–S匯編將.s
文件轉化成
.o文件使用的gcc
命令是:gcc
–c對應於匯編命令是
as鏈接將.o文件轉化成可執行程序使用的gcc
命令是:
gcc對應於鏈接命令是
ld總結起來編譯過程就上面的四個過程:預編譯、編譯、匯編、鏈接。

⑶ ARM編程只用C語言不要匯編可以嗎

可以的,但是c編譯器最終會生成匯編代碼的。

⑷ arm 匯編調用 C 函數問題

不同的編譯器對C 函數的處理不同,如armcc和gcc就有很多不同,從你的代碼來看,應該使用的是armcc編譯器;
應注意到代碼中涉及兩次返回:函數返回和中斷返回;
進入中斷後,lr寄存器保存的是中斷函數的返回地址,因此中斷返回時出棧時將該返回地址賦給PC即可,這一點比較好理解;

但函數返回的問題比較復雜:
1.為什麼不使用BL來調用C函數?
因為bl 指令跳轉范圍有限(好像4M左右吧),但bl指令可以將返回地址保存在lr中,當然,如果你的跳轉范圍不大,也可使用BL,則不需要ldr lr, =int_return 。
;而「ldr pc, =EINT_Handle」跳轉范圍為4G,但不會保存返回地址。
2. C函數使用 ldr pc, lr來實現返回,所以lr應預先保存好返回地址,即ldr lr, =int_return

⑸ arm匯編語言實現c語言程序

不懂C語言但稍微懂一點ARM Cortex-M3 匯編
很久沒寫匯編了,下邊這個沒調試直接編的不是範例,所以肯定寫錯了
編譯器GCC-ARM-NONE-EABI

應該有範例,你還是找範例吧

i: .int 20 @ int i=20

a: .int 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 @ 定義A數組

b: .int 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 @ 定義B數組

ldr r0, = i @ 把20存到R0

xunhuan1: @ if 裡面

ldr r1, = a @ 把A數組的首地址存到R1

ldr r2, [r1, r0] @ 取出首地址加20處的數據存到R2

ldr r3, = b @ 把B數組的首地址存到R3

ldr r4, [r3, r0] @取出首地址加20處的數據存到R4

mov r5, # 4 @ 把被乘數存到R5

mul r4, r4, r5 @ R4乘以4 b[i]*4
add r6, r2, r4 @ R2加上R4存到R6 a[i]+b[i]*4

str r6, [r1, r0] @ R6的數據存到A首地址加20的地方

lsrs r0, # 1 @ R0邏輯右移

bne xunhuan @ 判斷R0是不是等於0不等於跳到xunhuan

xunhuan: @ while 循環

sub r0, # 1 @ i減1

cmp r0, # 0 @比較R0和0

bge xunhuan1 @大於等於跳轉xunhuan1

⑹ arm編程與C語言的編程區別和方法

匯編主要是要了解CPU指令及用法,常說的是PC機的x86匯編,指令是x86的復雜指令集。
arm匯編是arm的精簡指令集,比x86容易學,程序格式倒是和x86匯編差不多。
C語言ARM的和x86的差不多,除了對硬體寄存器操作不同,其它語法和流程都一樣。
arm匯編程序每一行是指定arm core執行一條指令,每條指令都是硬體相關。
如:LDR R3, #1 ;用LDR指令將數值1放入R3寄存器准備參與運算
C語言與arm指令無關,只與邏輯運算有關,指定硬體地址的操作才與硬體相關;
如果用arm編譯器來編譯,每行可能編譯出1到多條arm指令。
如:i++; //變數 i 遞增1等效於LDR R3,#1 ;
用LDR指令將數值1放入R3寄存器准備參與運算ADD R2, R2, R3 ;
用ADD指令將R2、R3寄存器里的數值相加後放回R2寄存器以上等效匯編的R2、R3寄存器只是為了舉例,C語言不像匯編,不需要由程序員指定用哪個寄存器參與運算,編譯器編譯時會根據程序結構自動判斷選擇。
無論是c語言還是匯編語言,編譯器編譯後的結果是機器執行碼,很多人因為匯編語言比較難懂及指令相關,所以以為它就是機器語言,其實它仍是人類設計的編寫程序的語言,仍需要編譯器編譯成機器碼才能執行,它只是比C語言更接近硬體而已。

熱點內容
怎麼弄ld帳號和密碼 發布:2025-02-08 18:11:42 瀏覽:627
新逍客20發動機壓縮比 發布:2025-02-08 17:58:10 瀏覽:115
qq號和密碼我都知道為什麼登不上 發布:2025-02-08 17:52:21 瀏覽:872
寶塔伺服器ip進不去 發布:2025-02-08 17:52:18 瀏覽:382
擔保中介源碼 發布:2025-02-08 17:14:37 瀏覽:412
手機存儲卡速度測試 發布:2025-02-08 17:02:57 瀏覽:25
洪恩編程 發布:2025-02-08 17:02:19 瀏覽:814
linux遠程式控制制 發布:2025-02-08 17:02:16 瀏覽:153
珠心算演算法 發布:2025-02-08 17:00:37 瀏覽:919
動態ip可以做伺服器么 發布:2025-02-08 17:00:33 瀏覽:220