日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ATPCS和AAPCS

發布時間:2025/3/15 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ATPCS和AAPCS 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

基本概念

ATPCS (ARM-Thumb Procedure Call Standard)

規定了一些子程序間調用的基本規則,這些規則包括子程序調用過程中寄存器的使用規則,數據棧的使用規則,參數的傳遞規則。有了這些規則之后,單獨編譯的C語言程序就可以和匯編程序相互調用。
使用ADS的C語言編譯器編譯的C語言子程序滿足用戶指定的ATPCS類型。而對于匯編語言來說,則需要用戶來保證各個子程序滿足ATPCS的要求。

AAPCS (ARM Archtecture Procedure Call Standard)

2007年ARM公司正式推出了AAPCS標準,AAPCS是ATPCS的改進版,目前, AAPCS和ATPCS都是可用的標準

寄存器使用規則

子程序間通過寄存器R0~R3來傳遞參數。這時,寄存器R0~R3可記作a0~a3。被調用的子程序在返回前無需恢復寄存器R0~R3的內容。 在子程序中,使用寄存器R4~R11來保存局部變量。這時,寄存器R4~R11可以記作v1~v8。如果在子程序中使用了寄存器v1~v8中的某些寄存器,則子程序進入時必須保存這些寄存器的值,在返回前必須恢復這些寄存器的值。在Thumb程序中,通常只能使用寄存器R4~R7來保存局部變量。 寄存器R12用作過程調用中間臨時寄存器,記作IP。在子程序之間的連接代碼段中常常有這種使用規則。 寄存器R13用作堆棧指針,記作SP。在子程序中寄存器R13不能用作其他用途。寄存器SP在進入子程序時的值和退出子程序時的值必須相等。 寄存器R14稱為連接寄存器,記作LR。它用于保存子程序的返回地址。如果在子程序中保存了返回地址,寄存器R14則可以用作其他用途。 寄存器R15是程序計數器,記作PC。它不能用作其它用途。

堆棧使用規則

ATPCS規定堆棧為FD(Full Descending: sp指向最后一個壓入的值,數據棧由高地址向低地址生長)類型,即滿遞減堆棧,并且對堆棧的操作是8字節對齊。所以經常使用的指令就有STMFD和LDMFD。對于匯編程序來說,如果目標文件中包含了外部調用,則必須滿足下列條件:外部接口的堆棧必須是8字節對齊的。在匯編程序中使用PRESERVE8偽指令告訴連接器,本匯編程序數據是8字節對齊的。

參數傳遞規則

根據參數個數是否固定,可以將子程序分為參數個數固定的子程序和參數個數可變化的子程序。 這兩種子程序的參數傳遞規則是不一樣的。

4.1 參數個數可變子程序參數傳遞規則

對于參數個數可變的子程序,當參數個數不超過4個時,可以使用寄存器R0~R3來傳遞參數;當參數超過4個時,還可以使用堆棧來傳遞參數。 在傳遞參數時,將所有參數看作是存放在連續的內存字單元的字數據。然后,依次將各字數據傳遞到寄存器R0,R1,R2和R3中。如果參數多于4個,則將剩余的字數據傳遞到堆棧中。入棧的順序與參數傳遞順序相反,即最后一個字數據先入棧。

4.2 參數個數固定子程序參數傳遞規則

如果系統不包含浮點運算的硬件部件,浮點參數會通過相應的規則轉換成整數參數(若沒有浮點參數,此步省略),然后依次將各字數據傳送到寄存器R0~R3中。如果參數多于4個,將剩余的字數據傳送堆棧中,入棧的順序與參數順序相反,即最后一個字數據先入棧。在參數傳遞時,將所有參數看作是存放在連續的內存字單元的字數據。

子程序結果返回規則

子程序中結果返回的規則如下:

結果為一個32位整數時,可以通過寄存器R0返回; 結果為一個64位整數時,可以通過寄存器R0和R1返回; 結果為一個浮點數時,可以通過浮點運算部件的寄存器f0、d0或s0來返回; 結果為復合型浮點數(如復數)時,可以通過寄存器f0~fn或d0~dn來返回; 對于位數更多的結果,需要通過內存來傳遞。

  寄存器的使用規則:

  寄存器 R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15

  ATPCS名稱 a1 a2 a3 a4 v1 v2 v3 v4 WR v5 v6 SB v7 SL v8 FP

  IP SP LR PC 1.子程序間通過寄存器R0~R3來傳遞參數。被調用的子程序在返回前無須恢復寄存器R0~R3的內容。

  2.在子程序中,使用寄存器R4~R11來保存局部變量。這時,寄存器R4~R11可以記為v1~v8。如果在子程序中使用了寄存器v1~v8中的某些寄存器,則子程序進入時必須保存這些寄存器的值,在返回前必須恢復這些寄存器的值。在Thumb程序中,通常只能使用寄存器R4~R7來保存局部變量。另外R9,R10和R11還有一個特殊作用,分別記為:靜態基址寄存器SB,數據棧限制指針SL和楨指針FP。

  3.寄存器R12用做過程調用中間臨時寄存器IP。寄存器R13用做堆棧指針SP。在子程序中寄存器R13不能用做其它用途。寄存器SP在進入子程序時的值和退出子程序的值必須相等。寄存器R14稱為鏈接寄存器LR,它用于保存子程序的返回地址。如果在子程序中保存了返回地址,寄存器R14則可以用做其他用途。寄存器R15為程序計數器PC,不能用做其他用途。

  4.只有寄存器R0~R7,SP,LR和PC可以在Thumb狀態下使用,其中R7常常作為Thumb狀態的工作寄存器,記為WR。

  數據棧使用規則:

  1.滿降序棧(FD),且8字節對齊。

  關于PCS與ATPCS的一點介紹
  如果讀者使用的是ADS1.2編譯器,那么ATPCS.pdf文檔就在X:/Program Files/ARM/ADSv1_2/PDF/specs目錄里面。(X:/指的是ADS1.2編譯器所在的安裝盤)什么是PCS,什么是ATPCS?

  PCS即Procedure Call Standard(過程調用規范),ATPCS即ARM-THUMB procedure call standard。

  PCS規定了應用程序的函數可以如何分開地寫,分開地編譯,最后將它們連接在一起,所以它實際上定義了一套有關過程(函數)調用者與被調用者之間的協議。PCS強制實現如下約定:調用函數如何傳遞參數(即壓棧方法,以何種方式存放參數),被調用函數如何獲取參數,以何種方式傳遞函數返回值。PCS的制訂是一系列指標的“tradeoff(折衷)”(因為很大程度上涉及系統的一些性能),如會涉及生成代碼的大小,調試功能的支持,函數調用上下文處理速度以及內存消耗。當然,通過編譯器的支持可以讓生成的代碼有不同的特性,如gcc編譯選項可以支持或不支持framepointer來支持深入調試功能或提高程序運行性能。PCS是體系結構密切相關的,直接涉及編譯器如何使用處理器提供的應用寄存器,如編譯器使用什么寄存器作為棧指針,利用哪些寄存器作直接傳參等。值得注意的是,沒有誰規定說PCS是必須這樣而不是那樣的。它是應用相關的。任何一個操作系統和應用可以處于它自身的考慮定義自己的PCS。當然,如果那樣,也必須有自己的編譯器。而實際上,在一個處理器設計時,都會有某種假設,所以PCS某種程度上應該是一樣的。

  ATPCS是基于ARM指令集和THUMB指令集過程調用的規范。

  寄存器的使用規則:

  寄存器的使用必須滿足下面的規則:

  1. 子程序間通過寄存器R0 R3來傳遞參數,這時,寄存器R0R3可以記作A1-A4。被調用的子程序在返回前無需恢復寄存器R0-R3的內容。

  2. 在子程序中,使用寄存器R4 R11來保存局部變量.這時,寄存器R4-R11可以記作V1-V8。如果在子程序中使用到了寄存器V1-V8中的某些寄存器,子程序進入時必須保存這些寄存器的值,在返回前必須恢復這些寄存器的值;對于子程序中沒有用到的寄存器則不必進行這些操作。在Thumb程序中,通常只能使用寄存器R4-R7來保存局部變量。

  3. 寄存器R12用作子程序間scratch寄存器(用于保存SP,在函數返回時使用該寄存器出棧),記作ip。在子程序間的連接代碼段中常有這種使用規則。

  4. 寄存器R13用作數據棧指針,記作sp。在子程序中寄存器R13不能用作其他用途。寄存器sp在進入子程序時的值和退出子程序時的值必須相等。

  5. 寄存器R14稱為連接寄存器,記作lr。它用于保存子程序的返回地址。如果在子程序中保存了返回地址,寄存器R14則可以用作其他用途。

  6. 寄存器R15是程序計數器,記作pc。它不能用作其他用途。

  ATPCS規則 (2008-10-21 16:04:14) 標簽:atpcs arm 雜談 分類:嵌入式ARM

  基本ATPCS… 基本ATPCS規定了在子程序調用時的一些基本規則,包括以下三個方面的內容: 各寄存器的使用規則及其相應的名字; 數據棧的使用規則; 參數傳遞的規則. 相對于其他類型的ATPCS,滿足基本ATPCS的程序的執行速度更快,所占用的內存更少. 但是它不能提供以下的支持: ARM程序和THUMB程序相互調用; 數據以及代碼的位置無關的支持; 子程序的可重入性; 數據棧檢查的支持. 而派生的其他幾種特定的ATPCS就是在基本ATPCS的基礎上再添加其他的規則而形成的.其目的就是提供上述的功能…

   寄存器的使用規則:

   1. 子程序通過寄存器R0~R3來傳遞參數. 這時寄存器可以記作: A0~A3 , 被調用的子程序在返回前無需恢復寄存器R0~R3的內容.

   2. 在子程序中,使用R4~R11來保存局部變量,這時寄存器R4~R11可以記作: V1~V8 .如果在子程序中使用到V1~V8的某些寄存器,子程序進入時必須保存這些寄存器的值,在返回前必須恢復這些寄存器的值,對于子程序中沒有用到的寄存器則不必執行這些操作.在THUMB程序中,通常只能使用寄存器R4~R7來保存局部變量.

   3.寄存器R12用作子程序間scratch寄存器,記作ip; 在子程序的連接代碼段中經常會有這種使用規則.

   4. 寄存器R13用作數據棧指針,記做SP,在子程序中寄存器R13不能用做其他用途. 寄存器SP在進入子程序時的值和退出子程序時的值必須相等.

   5. 寄存器R14用作連接寄存器,記作lr ; 它用于保存子程序的返回地址,如果在子程序中保存了返回地址,則R14可用作其它的用途.

   6. 寄存器R15是程序計數器,記作PC ; 它不能用作其他用途.

   7. ATPCS中的各寄存器在ARM編譯器和匯編器中都是預定義的.

   數據棧的使用規則

   棧指針通??梢灾赶虿煌奈恢?當棧指針指向棧頂元素(即最后一個入棧的數據元素)時,稱為FULL棧.當棧指針指向與棧頂元素相鄰的一個元素時,稱為Empty棧. 數據棧的增長方向也可以不同. 當數據棧向內存減小的地址方向增長時,稱為Descending棧; 當數據棧向著內存地址增加的方向增長時,稱為Ascending棧. 綜合這兩種特點可以由以下4種數據棧: FD ED FA EA . ATPCS規定數據棧為FD類型,并對數據棧的操作是8字節對齊的,下面是一個數據棧的示例及相關的名詞.

   1.數據棧棧指針.stack pointer 指向最后一個寫入棧的數據的內存地址.

   2.數據棧的基地址.stack base 是指數據棧的最高地址.由于ATPCS中的數據棧是FD類型的,實際上數據棧中最早入棧數據占據的內存單元是基地址的下一個內存單元.

   3.數據棧界限.stack limit 是指數據棧中可以使用的最低的內存單元地址.

   4.已占用的數據棧.used stack 是指數據棧的基地址和數據棧棧指針之間的區域.其中包括數據棧棧指針對應的內存單元.

   5.數據棧中的數據幀(stack frames) 是指在數據棧中,為子程序分配的用來保存寄存器和局部變量的區域.

   異常中斷的處理程序可以使用被中斷程序的數據棧,這時用戶要保證中斷的程序數據棧足夠大. 使用ADS編譯器產生的目標代碼中包含了DRFAT2格式的數據幀.在調試過程中,調試器可以使用這些數據幀來查看數據棧中的相關信息.而對于匯編語言來說,用戶必須使用FRAME偽操作來描述數據棧中的數據幀.ARM匯編器根據這些偽操作在目標文件中產生相應的DRFAT2格式的數據幀.

   在ARMv5TE中,批量傳送指令LDRD/STRD要求數據棧是8字節對齊的,以提高數據的傳送速度.用ADS編譯器產生的目標文件中,外部接口的數據棧都是8字節對齊的,并且編譯器將告訴連接器: 本目標文件中的數據棧是8字節對齊的. 而對于匯編程序來說,如果目標文件中包含了外部調用,則必須滿足以下條件: 外部接口的數據棧一定是8位對齊的,也就是要保證在進入該匯編代碼后,直到該匯編程序調用外部代碼之間,數據棧的棧指針變化為偶數個字; 在匯編程序中使用PRESERVE8偽操作告訴連接器,本匯編程序是8字節對齊的.

   參數的傳遞規則.

   根據參數個數是否固定,可以將子程序分為參數個數固定的子程序和參數個數可變的子程序.這兩種子程序的參數傳遞規則是不同的.

   1.參數個數可變的子程序參數傳遞規則

   對于參數個數可變的子程序,當參數不超過4個時,可以使用寄存器R0~R3來進行參數傳遞,當參數超過4個時,還可以使用數據棧來傳遞參數. 在參數傳遞時,將所有參數看做是存放在連續的內存單元中的字數據。然后,依次將各名字數據傳送到寄存器R0,R1,R2,R3; 如果參數多于4個,將剩余的字數據傳送到數據棧中,入棧的順序與參數順序相反,即最后一個字數據先入棧. 按照上面的規則,一個浮點數參數可以通過寄存器傳遞,也可以通過數據棧傳遞,也可能一半通過寄存器傳遞,另一半通過數據棧傳遞.

   2.參數個數固定的子程序參數傳遞規則

   對于參數個數固定的子程序,參數傳遞與參數個數可變的子程序參數傳遞規則不同,如果系統包含浮點運算的硬件部件,浮點參數將按照下面的規則傳遞: 各個浮點參數按順序處理;為每個浮點參數分配FP寄存器;分配的方法是,滿足該浮點參數需要的且編號最小的一組連續的FP寄存器.第一個整數參數通過寄存器R0~R3來傳遞,其他參數通過數據棧傳遞.

   子程序結果返回規則

   1.結果為一個32位的整數時,可以通過寄存器R0返回.

   2.結果為一個64位整數時,可以通過R0和R1返回,依此類推.

   3.結果為一個浮點數時,可以通過浮點運算部件的寄存器f0,d0或者s0來返回.

   4.結果為一個復合的浮點數時,可以通過寄存器f0-fN或者d0~dN來返回.

   5.對于位數更多的結果,需要通過調用內存來傳遞.

幾種特定的ATPCS…

   A.支持數據棧限制檢查的ATPCS.

   如果在程序設計期間能夠準確地計算出程序所需的內存總量,就不需要進行數據棧的檢查,但是在通常情況下這是很難做到的,這時需要進行數據棧的檢查. 在進行數據棧的檢查時,使用寄存器R10作為數據棧限制指針,這時寄存器R10又記作sl.用戶在程序中不能控制該寄存器.具體來說,支持數據棧限制的ATPCS要滿足下面的規則: 在已經占有的棧的最低地址和sl之間必須有256字節的空間,也就是說,sl所指的內存地址必須比已經占用的棧的最低地址低256個字節.當中斷處理程序可以使用用戶的數據棧時,在已經占用的棧的最低地址和sl之間除了必須保留的256個字節的內存單元外,還必須為中斷處理預留足夠的內存空間; 用戶在程序中不能修改sl的值;數據棧棧指針sp的值必須不小于sl的值.

   與支持數據棧限制檢查的ATPCS相關的編譯/匯編選項有下面幾種: 選項/SWST 指示編譯器生成的代碼遵守支持數據棧限制檢查的ATPCS,用戶在程序設計期間不能夠準確計算程序所需的數據棧大小時,需要指定該選項;選項/noswst指示編譯器生成的代碼不支持數據棧限制檢查的功能,用戶在程序設計期間能夠準確計算出程序所需的數據棧大小,可以指定該選項,這個選項是默認的;選項/SWSTNA 如果匯編程序對于是否進行數據棧檢查無所謂,而與該匯編程序連接的其他程序指定了選項swst/noswst,這時使用該選項.

   編寫遵守支持數據棧限制檢查的ATPCS的匯編語言程序.

   對于C程序和C++程序來說,如果在編譯時指定了選項SWST,生成的目標代碼將遵守支持數據棧限制檢查的ATPCS. 對于匯編語言程序來說,如果要遵守支持數據棧限制檢查的ATPCS,用戶在編寫程序時必須滿足支持數據棧限制檢查的ATPCS所要求的規則,然后指定選項SWST,下面介紹用戶編寫匯編語言程序時的一些要求.

   葉子子程序是指不調用別的程序的子程序.

   數據棧小于256字節的葉子子程序不許要進行數據棧檢查,如果幾個子程序組合起來構成的葉子子程序數據棧也小于256字節,這個規則同樣適用; 數據棧小于256字節的非葉子子程序可以使用下面的代碼段來進行數據棧檢查.

  ARM程序使用: SUB sp,sp,#size ;#size 為sp和sl之間必須保留的空間大小   CMP sp,sl;BLLO _ARM_stack_overflowTHUMB程序使用: ADD sp,#-size ; #size為sp和sl之間必須保留的空間大小CMP sp,sl;BLLO _THUMB_stack_overflow數據棧大于256字節的子程序,為了保證sp的值不小于數據棧可用的內存單元最小的地址值,需要引入相應的寄存器.ARM程序使用下列代碼: SUB ip,sp,#size;CMP ip,sl;BLLO _ARM_stack_overflowTHUMB程序使用下列代碼: LDR wr,#-size;ADD wr,sp;CMP wr,sl;BLLO _THUMB_stack_overflow支持只讀段位置無關的ATPCS...支持可讀寫段位置無關的ATPCS...支持ARM程序和THUMB程序混合使用的ATPCS...

   在編譯或匯編時,使用/intework告訴編譯器或匯編器生成的目標代碼遵守支持ARM程序和THUMB程序混合使用的ATPCS,它用在以下場合: 程序中存在ARM程序調用THUMB程序的情況;程序中存在THUMB程序調用ARM程序的情況;需要連接器來進行ARM狀態和THUMB狀態切換的情況;.在下述情況下使用選項nointerwork:程序中不包含THUMB程序;用戶自己進行ARM程序和THUMB程序切換.需要注意的是:在同一個C/C++程序中不能同時有ARM指令和THUMB指令.

  處理浮點運算的ATPCS...ATPCS規則1 (2008-10-21 15:56:12) 標簽:atpcs規則雜談 分類:嵌入式ARM參數傳遞規則參數不超過4個時,可以使用寄存器R0~R3來傳遞參數,當參數超過4個時,還可以使用數據棧來傳遞參數。結果為一個32位整數時,可以通過寄存器R0返回結果為一個64位整數時,可以通過寄存器R0和R1返回,依次類推。匯編程序、C程序及C++程序相互調用C 程序調用匯編程序:o 匯編程序的設置要遵循ATPCS 規則,保證程序調用時參數的正確傳遞。o 在匯編程序中使用EXPORT 偽指令聲明本子程序,使其它程序可以調用此子程序。o 在C 語言程序中使用extern 關鍵字聲明外部函數(聲明要調用的匯編子程序),即可調用此匯編子程序。o 調用匯編的C 函數:o 示例#includeextern void strcopy(char *d,const char *s) //聲明外部函數,即要調用的匯編  //子程序int main(void){const char *srcstr=“First string-source”; //定義字符串常量char dstsrt[] =“Second string-destination”;//定義字符串變量printf(“Before copying:/n”);printf(“’%s’/n ‘%s/n,”srcstr,dststr); //顯示源字符串和目標字符串的內容strcopy(dststr,srcstr); //調用匯編子程序,R0=dststr,R1=srcstrprintf(“After copying:/n”)printf(“’%s’/n ‘%s/n,”srcstr,dststr); //顯示strcopy 復制字符串結果return(0);}o 被調用匯編子程序:AREA SCopy,CODE,READONLYEXPORT strcopy ;聲明匯編程序strcopy,以便外部程序引用strcopy ;R0 為目標字符串的地址;R1 為源字符串的地址 ;LDRB R2,[R1],#1 ;讀取字節數據,源地址加1STRB R2,[R0],#1 ;保存讀取的1 字節數據,目標地址加1CMP r2,#0 ;判斷字符串是否復制完畢BNE strcopy ;沒有復制完畢,繼續循環MOV pc,lr ;返回END匯編程序調用C程序o 匯編程序的設置要遵循ATPCS 規則,保證程序調用時參數的正確傳遞.o 在匯編程序中使用IMPORT 偽指令聲明將要調用的C 程序函數.o 在調用C 程序時,要正確設置入口參數,然后使用BL 調用.o 匯編調用C 程序的C 函數:int sum5(int a,lit b, int c,int d,int e){return(a+b+c+d+e); //返回5 個變量的和}o 匯編調用C 程序的匯編程序AREA sample, CODE,READONLYIMPORT sum5 ;聲明外部標號sum5,即C 函數sum5()CALLSUMSTMFD SP! {LR} ;LR 寄存器放棧ADD R1,R0,R0 ;設置sum5 函數入口參數,R0 為參數aADD R2,R1,R0 ;R1 為參數b,R2 為參數cADD R3,R1,R2,STR R3,[SP,# -4]! ;參數e 要通過堆棧傳遞ADD R3,R1,R1 ;R3 為參數dBL sum5 ;調用sum5(),結果保存在R0ADD SP,SP#4 ;修正SP 指針LDMFD SP,PC ;子程序返回END

  嵌入式C編程

  概述:

  C語言的優點是運行速度快、編譯效率高、移

  植性好和可讀性強。C語言支持模塊化程序設計,支持自頂

  向下的結構化程序設計方法。因此在嵌入式程序設計中經

  常會用到C語言程序設計。

  嵌入式C語言程序設計是利用基本的C語言知識,面向

  嵌入式工程實際應用進行程序設計。也就是說它首先是C語

  言程序設計,因此必須符合C語言基本語法,只是它是面向

  嵌入式的應用而設計的程序。

   C語言的“預處理偽指令”在嵌入式程序設計中的應用。

  1、文件包含偽指令

  格式:

  #include <頭文件名.h> ;標準頭文件

  #include “頭文件名.h” ;自定義頭文件

  2、宏定義偽指令

  格式:

  # define 宏標識符 宏體

  例:

n #define U32 unsigned intn #define U16 unsigned shortn #define S32 intn #define S16 short intn #define U8 unsigned charn #define S8 char

  3、條件宏:先測試是否定義過某宏標識符,然后決定如何處理。這樣做是為了避免重復定義。

  格式:

 #ifdef 宏標識符#undef 宏標識符#define 宏標識符 宏體#else#define 宏標識符 宏體#endif例:#ifdef INCLUDE_SERIAL#undef NUM_TTY#define NUM_TTY N_UART_CHANNELS#undef CONSOLE_TTY#define CONSOLE_TTY 0#undef CONSOLE_BAUD_RATE#define CONSOLE_BAUD_RATE 115200#endif

  4、條件編譯偽指令

  格式

 #if(條件表達式1)#elif(條件表達式2)#elif(條件表達式n)#else#endif

  這樣,編譯時,編譯器僅對#if()…#endif之間滿足某一條

  件表達式的源文件部分進行編譯。

  使用寄存器變量

  當對一個變量頻繁被讀寫時,需要反復訪問內存,從而花費大量的存取時間。

  為此,C語言提供了一種變量,即寄存器變量。這種變量存放在CPU的寄存器中,

  使用時,不需要訪問內存,而直接從寄存器中讀寫,從而提高效率。寄存器變量的

  說明符是register。對于循環次數較多的循環控制變量及循環體內反復使用的變量

  均可定義為寄存器變量,而循環計數是應用寄存器變量的最好候選者。

  例:

WORD Addition(BYTE n){register is=0; for(i=1;i<=n;i++){s=s+i;}return s;}

  活用位操作 (熟練掌握)

  使用C語言的位操作可以減少除法和取模的運算。在計算機程序中數

  據的位是可以操作的最小數據單位,理論上可以用“位運算”來完成所有的

  運算和操作,因而,靈活的位操作可以有效地提高程序運行的效率 。

  例:

int i,j;i = 879 / 16;j = 562 % 32;int i,j;i = 879 >> 4;j = 562 - (562 >> 5 << 5);例 int Ra ;//Ra[15:16]=11Ra &= ~(3<<15);

  C語言位運算除了可以提高運算效率外,在嵌入式

  系統的編程中,它的另一個最典型的應用,而且十分廣

  泛地正在被使用著的是位間的(&)、(|)、非(~)

  操作,這跟嵌入式系統的編程特點有很大關系。

  例:

rGPCDAT=(rGPCDAT&0xFFFFFFF0)|0x0ErINTMSK&=~(BIT_TIMER1)

  數據指針

  在嵌入式系統的編程中,常常要求在特定的內存單元讀寫內容,匯編有對應的

  MOV指令,而除C/C++以外的其它編程語言基本沒有直接訪問絕對地址的能力。在

  嵌入式系統的實際調試中,多借助C語言指針所具有的對絕對地址單元內容的讀寫能

  力。以指針直接操作內存多發生在如下幾種情況:

  n 某I/O芯片被定位在CPU的存儲空間而非I/O空間,而且寄存器對應于

  某特定地址;

  n 兩個CPU之間以雙端口RAM通信,CPU需要在雙端口RAM的特定單

  元(稱為mail box)書寫內容以在對方CPU產生中斷;

  n 讀取在ROM或FLASH的特定單元所燒錄的漢字和英文字模。

  例:

int *p = (int *)0xF000FF00 ;*p=0xABCD;#define rGPACON (*(volatile unsigned *)0x56000000);rGPACON=0x1234;

  關鍵字volatile

  一般這個修飾符用來告知編譯器,被修飾的變量是個“易變的”變

  量(volatile的本意是“易變的”),防止編譯器進行優化。將變量加上

  volatile修飾,則編譯器保證對此變量的讀寫操作都不會被優化。

  用法

  1、中斷服務程序中修改的供其它程序檢測的變量需要加volatile。

  2、多任務環境下各任務間共享的標志應該加volatile。

  3、存儲器映射的硬件寄存器通常也要加volatile說明,因為每次對它的讀寫都可能由不同意義。

總結

以上是生活随笔為你收集整理的ATPCS和AAPCS的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。