嵌入式中C和彙編的一些技巧

2021-04-18 11:06:50 字數 2266 閱讀 9496

arm彙編部分:a. 條件執行

cmp r0,#5

beq bypass

add r1,r1,r0

sub r1,r1,r2

bypass ......

可以替代為:

cmp r0,#5

addne r1,r1,r0

subne r1,r1,r2

如果被跳過的指令序列並不進行複雜的操作,使用條件執行都要比使用轉移好,因為arm轉義指令一般要用3個週期來執行。

對於以下的條件執行可以這樣來寫彙編:

; if ( (a = = b) && (c = = d) )   e++

cmp r0,r1

cmpeq r2,r3

addeq r4,r4,#1

c語言部分:

a.  很多人認為以下兩種變數定義空間效率一樣的:

①        char a;

short b;

char c;

int d;

②        char a;

char b;

short c;

int d;

其實不然,定義次序的不同導致最終映像中不同的資料布局,實際中第二種定義方式能夠節約更多的儲存空間,所以在變數聲名時,最好把所有相同型別的變數放在一起定義,這樣可以優化儲存器布局。

b.  我們總是設法使用short或者char來定義變數,認為這樣能夠節省儲存空間,但也有例外,我們先來看下這幾段c**及其相應的彙編:

①  c**:

int addition(int a)

彙編:add a1,a1,#1

②  c**:

short addition(short a)

彙編:

add a1,a1,#1

mov a1,a1,lsl #16

mov a1,a1,asr #16

mov pc,lr

③  c**:

char addition(char a)

彙編:

add a1,a1,#1

and a1,a1,# &ff

mov pc,lr

因為char 型別、short型別分別是8位、16位,完成加法操作後,需要在32位的暫存器中進行符號擴充套件,所以使用32位的int以及unsinged int做加法效率最高。

c.冗餘變數要消耗空間,許多人都不贊同使用它,但是下面這種情況就不同了。

int m ( void );

int n ( void );

int fg;

① void func_1 ( void )

fg += m ( );

fg += n ( );

②  void func_2 ( void )

int tmp = fg;

tmp += m ( );

tmp += n ( );

fg = tmp;

在func_1 ( ) 中每次對全域性變數fg的加法操作都需要從儲存器load到暫存器裡,加完資料後還要store回原來的儲存器,所以這個函式就進行了兩次load和兩次store操作。在func_2 ( ) 中,tmp作為區域性變數,系統為其分配一暫存器,首先執行一次load操作後,由tmp進行加法,最後只需一次store操作把結果送給fg,節省了很多時間,畢竟讀/寫儲存器的時間耗費要比讀/寫暫存器高得多。

d.關於計數迴圈的問題,一般我們都會使用累加計數的方式,遞減計數用得比較少,雖然從c**上看累加和遞減兩種方式時間複雜度相同,但是在對時間要求嚴格的嵌入式領域,這兩者執行時間還是有差別的。

①  累加計數方式:

for ( i = 1; i < times; i ++ )

tmp = tmp * i ;

彙編:0x06: mul r2,r1,r2

0x10: add r1,r1,#1

0x14: cmp r2,r0

0x18: ble 0x06

②  遞減計數方式:

for ( i = times; i > 1; i -- )

tmp = tmp * i ;

彙編:0x06: mul r0,r1,r0

0x10: sub r1,r1,#1

0x14: bne 0x06

從上面的彙編可以看出,累加計數需要用到專門的cmp指令來判斷條件,而遞減計數只需要利用條件執行的ne進行判別,當迴圈次數的量很大的話時間效率就有差別了。

一些C函式 嵌入式Linux

1.exit 電腦函式 函式名 exit 所在標頭檔案 stdlib.h 如果是 vc6.0 的話標頭檔案為 windows.h 功 能 關閉所有檔案,終止正在執行的程序。exit 1 表示異常退出.這個1是返回給作業系統的。exit x x不為0 都表示異常退出 exit 0 表示正常退出 exi...

嵌入式 C語言位操作的一些技巧彙總

下面分享關於位操作的一些筆記 首先,以下是按位運算子 在嵌入式程式設計中,常常需要對一些暫存器進行配置,有的情況下需要改變乙個位元組中的某一位或者幾位,但是又不想改變其它位原有的值,這時就可以使用按位運算子進行操作。下面進行舉例說明,假如有乙個8位的test暫存器 當我們要設定第0位bit0的值為1...

嵌入式開發中的一些細節

從事開發一年多,發現到一些小細節,會影響到自己開發的效率,特總結如下,以免犯錯 1.標準c中str系列的函式中,0 有特殊的含義 字串結束 所以如果要操作具有0x00 有實際意義 的字串,不應該用該系列的函式。例 有字串 0nocookie 0nocache 0 本義是想用 0 來表示分隔符,分隔出...