嵌入式系統(tǒng)原理與應(yīng)用 課件 第4章 Cortex M3匯編語(yǔ)言程序設(shè)計(jì)基礎(chǔ)2_第1頁(yè)
嵌入式系統(tǒng)原理與應(yīng)用 課件 第4章 Cortex M3匯編語(yǔ)言程序設(shè)計(jì)基礎(chǔ)2_第2頁(yè)
嵌入式系統(tǒng)原理與應(yīng)用 課件 第4章 Cortex M3匯編語(yǔ)言程序設(shè)計(jì)基礎(chǔ)2_第3頁(yè)
嵌入式系統(tǒng)原理與應(yīng)用 課件 第4章 Cortex M3匯編語(yǔ)言程序設(shè)計(jì)基礎(chǔ)2_第4頁(yè)
嵌入式系統(tǒng)原理與應(yīng)用 課件 第4章 Cortex M3匯編語(yǔ)言程序設(shè)計(jì)基礎(chǔ)2_第5頁(yè)
已閱讀5頁(yè),還剩41頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

嵌入式系統(tǒng)設(shè)計(jì)西安郵電大學(xué)計(jì)算機(jī)學(xué)院王忠民基于ARMCortexM3IP核的程序設(shè)計(jì)(1)4.1ARM匯編語(yǔ)言的程序結(jié)構(gòu)4.2ARM匯編器偽指令 4.2.1段定義偽指令 4.2.2數(shù)據(jù)定義偽指令 4.2.3過程定義偽指令 4.2.4宏定義偽指令 4.2.5其他偽指令4.3ARM匯編語(yǔ)言程序設(shè)計(jì)

4.3.1順序程序

4.3.2分支程序

4.3.3循環(huán)程序

4.3.4過程(子程序)調(diào)用第4章基于ARMCortexM3IP核的程序設(shè)計(jì)---學(xué)習(xí)內(nèi)容基于ARMCortexM3IP核的程序設(shè)計(jì)(2)4.4C與匯編混合編程

4.4.1ARM架構(gòu)過程調(diào)用標(biāo)準(zhǔn)AAPCS (ARMArchitectureProcedureCallStandard)

4.4.2C程序內(nèi)嵌匯編代碼 4.4.3C程序調(diào)用匯編過程 4.4.4匯編程序調(diào)用C函數(shù) 4.4.5C與匯編程序變量互訪

第4章基于ARMCortexM3IP核的程序設(shè)計(jì)---ARM架構(gòu)過程調(diào)用標(biāo)準(zhǔn)AAPCS

ARM架構(gòu)過程調(diào)用標(biāo)準(zhǔn)AAPCSC程序內(nèi)嵌匯編代碼 C程序調(diào)用匯編過程

匯編程序調(diào)用C函數(shù)C與匯編程序變量互訪

如果工程比較小,使用純匯編常常是可行的,而且你能隨心欲地優(yōu)化和控制程序。不過,你的開發(fā)周期會(huì)變長(zhǎng)。尤其是當(dāng)工程變大,需要處理比較復(fù)雜的數(shù)據(jù)結(jié)構(gòu),以及要管理函數(shù)庫(kù)時(shí),你將發(fā)現(xiàn)匯編會(huì)使工作量激增。各種地址和間接引用千頭萬緒;bug劈頭蓋臉;甚至好幾天都改不完,簡(jiǎn)直就是自虐。當(dāng)然,如果你想成為系統(tǒng)開發(fā)的大蝦(大咖),就必須以“我不下地獄誰(shuí)下地獄”的決心,去勇敢面對(duì),后天下樂而樂。不論如何,時(shí)間寶貴。我們應(yīng)該以C來實(shí)現(xiàn)程序的大框架,而本著好鋼用在刀刃上的原則來使用匯編,因?yàn)橹挥性诓欢嗟奶厥鈭?chǎng)合是非使用匯編語(yǔ)言不可的,它們是:無法用C寫成的函數(shù),如操作特殊功能寄存器,以及實(shí)施互斥訪問。在危急關(guān)頭執(zhí)行的程序(如,NMI服務(wù)例程)。存儲(chǔ)器極度受限,只有使用匯編才可能把程序或數(shù)據(jù)擠進(jìn)去。執(zhí)行頻率非常高的子程,如操作系統(tǒng)的調(diào)度程序。與處理器體系結(jié)構(gòu)相關(guān)的子程序,如上下文切換。

對(duì)性能要求極高的應(yīng)用,如防空炮的火控系統(tǒng)。第4章基于ARMCortexM3IP核的程序設(shè)計(jì)---為什么要C與匯編混合編程第4章基于ARMCortexM3IP核的程序設(shè)計(jì)---為什么要C與匯編混合編程

在進(jìn)行ARM嵌入式系統(tǒng)開發(fā)時(shí),混合使用C和匯編語(yǔ)言進(jìn)行軟件設(shè)計(jì)的原因主要有以下幾點(diǎn):性能優(yōu)化:匯編語(yǔ)言是直接與機(jī)器硬件打交道的編程語(yǔ)言,它能夠精確控制CPU的每一個(gè)操作。在某些需要高性能的場(chǎng)景下,如中斷處理、實(shí)時(shí)控制等,使用匯編語(yǔ)言可以編寫出更高效的代碼。而C語(yǔ)言雖然抽象層次較高,易于編寫和理解,但在某些情況下可能無法達(dá)到匯編語(yǔ)言所能提供的性能。因此,在關(guān)鍵部分使用匯編語(yǔ)言,而在非關(guān)鍵部分使用C語(yǔ)言,可以在保證代碼可讀性和可維護(hù)性的同時(shí),實(shí)現(xiàn)性能的優(yōu)化。硬件操作:某些硬件操作,特別是與底層硬件緊密相關(guān)的操作,如直接訪問內(nèi)存地址、設(shè)置寄存器值等,使用匯編語(yǔ)言會(huì)更加方便和高效。這些操作在C語(yǔ)言中可能難以直接實(shí)現(xiàn),或者實(shí)現(xiàn)起來較為復(fù)雜。通過使用匯編語(yǔ)言,可以直接編寫與硬件相關(guān)的代碼,實(shí)現(xiàn)對(duì)硬件的精確控制。系統(tǒng)啟動(dòng):在嵌入式系統(tǒng)的啟動(dòng)過程中,往往涉及到對(duì)硬件的初始化、操作系統(tǒng)的加載等復(fù)雜操作。這些操作通常需要使用匯編語(yǔ)言來完成,因?yàn)閰R編語(yǔ)言能夠直接操作硬件,并且在系統(tǒng)啟動(dòng)的早期階段,C語(yǔ)言運(yùn)行環(huán)境可能還沒有完全建立。代碼移植性:雖然匯編語(yǔ)言與特定的硬件平臺(tái)緊密相關(guān),但在某些情況下,使用匯編語(yǔ)言編寫的代碼可能更容易在不同的硬件平臺(tái)之間進(jìn)行移植。這是因?yàn)閰R編語(yǔ)言直接反映了硬件的特性和指令集,只要目標(biāo)平臺(tái)支持相同的指令集,匯編代碼通常只需要進(jìn)行少量的修改就可以在新的平臺(tái)上運(yùn)行。C語(yǔ)言與匯編語(yǔ)言分別有各自的優(yōu)缺點(diǎn)。采用C語(yǔ)言進(jìn)行算法設(shè)計(jì)和程序編寫時(shí),是面向過程的,整個(gè)流程清晰,實(shí)現(xiàn)起來較容易,且提供很多接口函數(shù),但編譯時(shí)生成的可執(zhí)行文件大,因此實(shí)時(shí)性難以控制,也不能對(duì)硬件進(jìn)行直接的操作。采用匯編語(yǔ)言進(jìn)行程序設(shè)計(jì)時(shí),比C語(yǔ)言的流程更不容易理解和設(shè)計(jì),但匯編語(yǔ)言匯編生成的可執(zhí)行文件小,執(zhí)行速度快,實(shí)時(shí)性高,且能對(duì)內(nèi)存,外設(shè)端口進(jìn)行直接的讀寫操作。如果將二者結(jié)合起來進(jìn)行開發(fā),能簡(jiǎn)化編程難度,保證實(shí)時(shí)性,并能對(duì)硬件進(jìn)行訪問。第4章基于ARMCortexM3IP核的程序設(shè)計(jì)---ARM架構(gòu)過程調(diào)用標(biāo)準(zhǔn)AAPCSARM架構(gòu)過程調(diào)用標(biāo)準(zhǔn)AAPCS(ARMArchitectureProcedureCallStandard)是ARM公司制定的一套用于ARM處理器體系結(jié)構(gòu)的函數(shù)調(diào)用和返回機(jī)制的標(biāo)準(zhǔn)。它旨在確保編譯器生成的代碼在ARM架構(gòu)上的不同模塊之間具有良好的互操作性和兼容性。通過遵循AAPCS,開發(fā)者可以更加高效地使用ARM架構(gòu)的寄存器和堆棧資源,減少潛在的兼容性問題,提高代碼的可移植性和可維護(hù)性。Thumb-2指令集在過程調(diào)用時(shí),參數(shù)的傳遞遵循AAPCS過程調(diào)用標(biāo)準(zhǔn)。更早期的程序調(diào)用標(biāo)準(zhǔn)ATPCS(ARMThumbProcedureCallStandard)是為Thumb指令集定義的一種過程調(diào)用標(biāo)準(zhǔn),隨著ARM架構(gòu)的發(fā)展和Thumb-2指令集的引入,AAPCS逐漸取代了ATPCS,成為更廣泛接受的程序調(diào)用標(biāo)準(zhǔn)。推出AAPCS的主要目的是為了定義ARM架構(gòu)中過程調(diào)用和返回的約定,確保不同編譯器生成的代碼之間的兼容性,以及不同模塊之間的互操作性。它規(guī)定了一些過程間調(diào)用的基本規(guī)則,包括過程調(diào)用過程中寄存器的使用規(guī)則、數(shù)據(jù)棧的使用規(guī)則、參數(shù)的傳遞規(guī)則等。這些規(guī)則有助于確保單獨(dú)編譯的C語(yǔ)言程序能夠和匯編程序相互調(diào)用,提高了代碼的兼容性和互操作性。根據(jù)AAPCS規(guī)定,在參數(shù)傳遞過程中,主要考慮以下幾種情況:1.參數(shù)傳遞2.返回值傳遞3.堆棧使用4.函數(shù)調(diào)用中的寄存器使用第4章基于ARMCortexM3IP核的程序設(shè)計(jì)---參數(shù)傳遞(1)通過寄存器傳遞

AAPCS規(guī)定,前四個(gè)整數(shù)或指針類型的參數(shù)通常通過寄存器R0-R3進(jìn)行傳遞。這種機(jī)制有效地提高了函數(shù)調(diào)用的效率,因?yàn)榧拇嫫髟L問通常比堆棧訪問更快。對(duì)于64位的數(shù)據(jù)類型(如longlong),低32位放在R0或R2中,高32位放在R1或R3中。舉例:假設(shè)有一個(gè)函數(shù)intmultiply(inta,intb),它接受兩個(gè)整數(shù)參數(shù)并返回它們的乘積。在調(diào)用multiply函數(shù)時(shí),參數(shù)a和b會(huì)分別被放置在R0和R1寄存器中。

(2)通過堆棧傳遞當(dāng)參數(shù)數(shù)量超過四個(gè)時(shí),額外的參數(shù)將通過堆棧進(jìn)行傳遞。系統(tǒng)會(huì)自動(dòng)將這些參數(shù)推送到堆棧上,并確保它們按照正確的順序排列。堆棧的增長(zhǎng)方向通常是向低地址方向,這意味著新的參數(shù)會(huì)被推送到當(dāng)前堆棧指針以下的地址。第4章基于ARMCortexM3IP核的程序設(shè)計(jì)---返回值傳遞(1)通過寄存器返回函數(shù)的返回值通常保存在R0寄存器中。如果返回值是32位或以下的整型、指針或單精度浮點(diǎn)數(shù),那么它就直接放在R0中;對(duì)于64位的返回值(如longlong或雙精度浮點(diǎn)數(shù)),R0保存低32位,R1保存高32位;對(duì)于更大的數(shù)據(jù)結(jié)構(gòu)(如結(jié)構(gòu)體),返回值通常是通過指針傳遞的,該指針指向由調(diào)用者分配的內(nèi)存空間,函數(shù)將結(jié)果寫入這塊內(nèi)存。舉例:考慮一個(gè)函數(shù)longlongmultiply64(longlonga,longlongb),它接受兩個(gè)64位整數(shù)并返回它們的乘積。在調(diào)用multiply64函數(shù)后,其64位返回值會(huì)被保存在R0和R1寄存器中,其中R0保存低32位,R1保存高32位。(2)通過內(nèi)存返回對(duì)于非常大的返回值或不適合通過寄存器傳遞的數(shù)據(jù)結(jié)構(gòu),通常的做法是通過指針返回。函數(shù)接收一個(gè)指向預(yù)先分配好的內(nèi)存的指針作為參數(shù),然后將結(jié)果寫入該內(nèi)存區(qū)域。第4章基于ARMCortexM3IP核的程序設(shè)計(jì)---函數(shù)調(diào)用中的寄存器使用(1)調(diào)用者保存的寄存器

R0-R3、R12屬于調(diào)用者保存的寄存器,意味著調(diào)用者需要確保這些寄存器在調(diào)用函數(shù)前后的值保持不變。(2)被調(diào)用者保存的寄存器函數(shù)或子程序應(yīng)該保持R4-R11、R13和R14的數(shù)值不變。若這些寄存器在函數(shù)或子程序執(zhí)行期間被修改,則其應(yīng)該保持在棧中并在返回調(diào)用代碼前恢復(fù)。這些寄存器被稱為“被調(diào)用者保存寄存器”。第4章基于ARMCortexM3IP核的程序設(shè)計(jì)---C與匯編混合編程ARM架構(gòu)過程調(diào)用標(biāo)準(zhǔn)AAPCSC程序內(nèi)嵌匯編代碼 C程序調(diào)用匯編過程

匯編程序調(diào)用C函數(shù)C與匯編程序變量互訪

第4章基于ARMCortexM3IP核的程序設(shè)計(jì)---C程序內(nèi)嵌匯編代碼 在KeilMDK5開發(fā)環(huán)境中,使用Thumb-2指令系統(tǒng)時(shí),可以使用內(nèi)嵌匯編(InlineAssembly)來直接在C語(yǔ)言程序中插入?yún)R編指令。允許執(zhí)行一些低級(jí)的、C語(yǔ)言無法直接處理的操作,或者優(yōu)化某些關(guān)鍵代碼段。在KeilMDK5中,C語(yǔ)言程序中內(nèi)嵌匯編語(yǔ)句格式如下:__asm //asm前面使用的是雙下劃線{

匯編語(yǔ)句1

匯編語(yǔ)句2

匯編語(yǔ)句3

……}需要說明的是,在內(nèi)嵌匯編中,一般不要直接指定物理寄存器,而要讓編譯器自動(dòng)分配;如果一定要使用物理寄存器,要注意以下原則:R12與R13常用于存放中間編譯結(jié)果,不能使用;R0~R3在過程調(diào)用中用于傳遞參數(shù),不能使用;R14用于過程調(diào)用的返回,也不能使用。第4章基于ARMCortexM3IP核的程序設(shè)計(jì)---C程序內(nèi)嵌匯編代碼 例:編寫一個(gè)由startup.s和My_C_Functions.c兩個(gè)文件組成的工程,在C函數(shù)中嵌套匯編語(yǔ)句實(shí)現(xiàn)三個(gè)變量相加。

一個(gè)由匯編啟動(dòng)文件和C用戶程序構(gòu)成的工程第4章基于ARMCortexM3IP核的程序設(shè)計(jì)---C程序內(nèi)嵌匯編代碼 li4_10_C_embedded_asm工程中的C文件My_C_Functions.c代碼如下:int addxyz(intx,inty,intz);//聲明函數(shù)addxyz()int My_C_Functions(void){ int sum; sum=addxyz(1,2,3); //調(diào)用addxyz()函數(shù)

return0; }intaddxyz(intx,inty,intz) //函數(shù)addxyz()的三個(gè)實(shí)參1,2,3分別傳遞給x,y,z {__asm { add x,x,y //根據(jù)AAPCS參數(shù)傳遞規(guī)則,x,y,z分別對(duì)應(yīng)寄存器R0,R1,R2 add x,x,z } return(x); }注意參數(shù)如何傳遞第4章基于ARMCortexM3IP核的程序設(shè)計(jì)---C函數(shù)中內(nèi)嵌匯編指令(C工程不講)1111_C_Embeded_Asm#include<stdio.h>#include<string.h>#defineITM_Port8(n)(*((volatileunsignedchar*)(0xE0000000+4*n)))#defineITM_Port16(n)(*((volatileunsignedshort*)(0xE0000000+4*n)))#defineITM_Port32(n)(*((volatileunsignedlong*)(0xE0000000+4*n)))#defineDEMCR(*((volatileunsignedlong*)(0xE000EDFC)))//DebugExceptionandMonitorControlRegister,DEMCR#defineTRCENA0x01000000struct__FILE{inthandle;};FILE__stdout;FILE__stdin;intbadf(intx);intmax(inta,intb,intc);intfputc(intch,FILE*f){ if(DEMCR&TRCENA) { while(ITM_Port32(0)==0); ITM_Port8(0)=ch; } return(ch);}

intmain(void){int ch;int x;ch=badf(10);printf("ch=%d",ch);x=max(4,1,20);printf("\nmax=%d",x);return0;}intbadf(intx){__asm {addx,x,1} return(x);}intmax(inta,intb,intc){ intmaxtem; __asm {mov maxtem,a cmp maxtem,b bhi loop1 mov maxtem,bloop1: cmp maxtem,c bhi loop2 mov maxtem,cloop2: mov a,maxtem } return(a);}

問題描述:在C工程的main()文件中定義了二個(gè)函數(shù):badf()—加1;max()—求三個(gè)數(shù)最大數(shù)。兩個(gè)函數(shù)中均使用了內(nèi)嵌匯編指令實(shí)現(xiàn)相關(guān)功能第4章基于ARMCortexM3IP核的程序設(shè)計(jì)---C調(diào)用匯編過程ARM架構(gòu)過程調(diào)用標(biāo)準(zhǔn)AAPCS

C程序內(nèi)嵌匯編代碼

C程序調(diào)用匯編過程

匯編程序調(diào)用C函數(shù)C與匯編程序變量互訪

C程序中調(diào)用匯編過程的具體步驟如下:(1)在C文件中用關(guān)鍵字extern聲明要調(diào)用的匯編過程的原型,并定義好形參,然后就可以在C程序中調(diào)用該過程了。(2)在匯編程序中用偽指令EXPORT導(dǎo)出要調(diào)用的過程名,并定義該過程,使用BXLR返回;(3)如果在調(diào)用時(shí)需傳遞參數(shù),參數(shù)1,2,3,4默認(rèn)使用寄存器R0~R3傳遞,如果參數(shù)個(gè)數(shù)多于4個(gè),則使用堆棧傳遞;(4)如果有返回值,則默認(rèn)用R0返回。第五章CortexM3匯編語(yǔ)言程序設(shè)計(jì)基礎(chǔ)---C調(diào)用匯編過程*.c(C文件)externintaddxy(intx,inty);….a=addxy(a,b);……*.asm(匯編文件) EXPORT addxyaddxy proc…… BX LR endp圖C程序中調(diào)用匯編過程示意例:在C文件My_C_Functions.c中調(diào)用在匯編程序addxy.s中定義的過程addxy,實(shí)現(xiàn)將在C中定義的兩個(gè)變量a和b相加。第五章CortexM3匯編語(yǔ)言程序設(shè)計(jì)基礎(chǔ)---C調(diào)用匯編過程圖C調(diào)用匯編過程的工程組成匯編程序addxy.s的代碼如下: AREA armxy,CODE,READONLY EXPORT addxyaddxyproc ADD R0,R0,R1 BX LR endp

endC文件My_C_Functions.c代碼如下: externintaddxy(intx,inty); intMy_C_Functions(void){ inta=1,b=2; a=addxy(a,b); return0; } li4_11_C_Call_Asm1例:

在C文件My_C_Functions.c中定義了一個(gè)十個(gè)元素的整型數(shù)組變量intn[],調(diào)用在匯編程序max_v.s中定義的過程N(yùn)_Paixu,實(shí)現(xiàn)將在C中定義的數(shù)組n用冒泡法實(shí)現(xiàn)從小到大排序。第五章CortexM3匯編語(yǔ)言程序設(shè)計(jì)基礎(chǔ)---C調(diào)用匯編過程匯編程序max_v.s的代碼如下:

AREA MAX, CODE, READONLY EXPORT N_PaixuN EQU 10 N_Paixu PROC MOV R1,#0 MOV R2,#0 LOOPI ADD R3,R0,R1,LSL#2 MOV R4,R3 ADD R2,R1,#1 MOV R5,R4 LDR R6,[R4] LOOPJ ADD R5,R5,#4 LDR R7,[R5] CMP R6,R7 BLT NEXT LDR R7,[R5] STR R6,[R5] MOV R6,R7 NEXT ADD R2,R2,#1 CMP R2,#N BLT LOOPJ LDR R7,[R3] STR R6,[R3] ADD R1,R1,#1 CMP R1,#N-1 BLT LOOPI BX LR ENDP ENDC文件My_C_Functions.c代碼如下:

externintN_Paixu(int*num); intMy_C_Functions(void){ intn[]={10,9,8,7,6,5,4,3,2,1}; N_Paixu(n); return(0); }li4_12_C_Call_Asm2在主調(diào)程序C中用EXTERN關(guān)鍵字聲明被調(diào)用的外部匯編過程;在被調(diào)的匯編過程中使用EXPORT作聲明本過程可以被外部調(diào)用。1111_C_Call_Asm1#defineITM_Port32(n)(*((volatileunsignedlong*)(0xE0000000+4*n)))#defineDEMCR(*((volatileunsignedlong*)(0xE000EDFC)))//DebugExceptionandMonitorControlRegister,DEMCR#defineTRCENA0x01000000struct__FILE{inthandle;};FILE__stdout;FILE__stdin;intfputc(intch,FILE*f)//???????{ if(DEMCR&TRCENA) { while(ITM_Port32(0)==0); ITM_Port8(0)=ch; } return(ch);}externintadd_s(intx,inty);intmain(){ inta=1,b=2,c; printf("\na=%d",a); printf("\nb=%d",b);

c=add_s(a,b); printf("\na+b=%d",c); return0;}

AREAARM_add,CODE,READONLY

EXPORTadd_sadd_s ADDr0,r0,r1 MOVpc,lr end第五章CortexM3匯編語(yǔ)言程序設(shè)計(jì)基礎(chǔ)---C調(diào)用匯編過程(C工程不講)

問題描述:在C工程的main()函數(shù)中定義了三個(gè)變量(inta=1,b=2,c;),要求編寫匯編過程實(shí)現(xiàn)c=a+b

在主調(diào)程序C中用EXTERN關(guān)鍵字聲明被調(diào)用的外部匯編過程;在被調(diào)的匯編過程中使用EXPORT作聲明本過程可以被外部調(diào)用。1111_C_Call_Asm3#defineITM_Port32(n)(*((volatileunsignedlong*)(0xE0000000+4*n)))#defineDEMCR(*((volatileunsignedlong*)(0xE000EDFC)))//DebugExceptionandMonitorControlRegister,DEMCR#defineTRCENA0x01000000struct__FILE{inthandle;};FILE__stdout;FILE__stdin;intfputc(intch,FILE*f)//???????{ if(DEMCR&TRCENA) {while(ITM_Port32(0)==0); ITM_Port8(0)=ch;} return(ch);}externintmax_v(int*num);intmain(){ intn[]={10,9,8,7,6,5,4,3,2,1}; intI; printf("TheOriginalNum:\n"); for(i=0;i<10;i++) {printf("n[%d]=%d",i,n[i]);}

max_v(n); printf("\nTherearrangedNum:\n"); for(i=0;i<10;i++) {printf("n[%d]=%d",i,n[i]);} return(0);}

AREAMAX, CODE, READONLY

EXPORTmax_vNEQU10 max_v

MOV R1,#0 MOV R2,#0 LOOPI ADD R3,R0,R1,LSL#2 MOV R4,R3 ADD R2,R1,#1 MOV R5,R4 LDR R6,[R4] LOOPJ ADD R5,R5,#4 LDR R7,[R5] CMP R6,R7 BLT NEXT ;SWP R7,R6,[R5] ldr r7,[r5] str r6,[r5] MOV R6,R7 NEXT ADD R2,R2,#1 CMP R2,#N BLT LOOPJ ldr r7,[r3] str r6,[r3] ADD R1,R1,#1 CMP R1,#N-1 BLT LOOPI BX LR END第五章CortexM3匯編語(yǔ)言程序設(shè)計(jì)基礎(chǔ)---C調(diào)用匯編過程(C工程不講)

問題描述:在C工程的main()函數(shù)中定義了一個(gè)十個(gè)元素的整型數(shù)組變量(intn[]),要求編寫匯編過程實(shí)現(xiàn)冒泡排序第4章基于ARMCortexM3IP核的程序設(shè)計(jì)---C與匯編混合編程典型的開發(fā)流程---Cortex‐M3權(quán)威指南---第十章Cortex-M3的低層編程

ARM架構(gòu)過程調(diào)用標(biāo)準(zhǔn)AAPCS

C程序內(nèi)嵌匯編代碼

C程序調(diào)用匯編過程

匯編程序調(diào)用C函數(shù)C與匯編程序變量互訪

第4章基于ARMCortexM3IP核的程序設(shè)計(jì)--匯編調(diào)用C函數(shù)2025/11/28*.s(匯編程序)IMPORT My_C_Functions….LDR R0,=My_C_FunctionsBLX R0*.c(C程序)externintN_Paixu(int*num);intMy_C_Functions(void){ ……return(0); }匯編程序中調(diào)用C函數(shù)示意在匯編文件中,用偽指令I(lǐng)MPORT將要調(diào)用的C函數(shù)引用;在C文件中不需要做任何聲明;如果在函數(shù)調(diào)用時(shí)需傳遞參數(shù),參數(shù)1,2,3,4默認(rèn)使用寄存器R0~R3傳遞,如果參數(shù)個(gè)數(shù)多于4個(gè),則使用堆棧傳遞;如果函數(shù)有返回值,則默認(rèn)用R0返回。應(yīng)用場(chǎng)景:匯編調(diào)C這種情況在嵌入式系統(tǒng)開發(fā)中相對(duì)少見,但在某些特殊情況下,匯編代碼可能需要調(diào)用C函數(shù)。例如,在啟動(dòng)代碼或底層初始化代碼中,可能需要調(diào)用一些用C語(yǔ)言編寫的庫(kù)函數(shù)。li4_13_ASM_CALL_C1第4章基于ARMCortexM3IP核的程序設(shè)計(jì)--匯編調(diào)用C函數(shù)2025/11/28例4-13在匯編編寫的啟動(dòng)文件startup.s文件中,通過R0、R1、R2傳遞參數(shù),調(diào)用在C程序中定義的求和函數(shù),實(shí)現(xiàn)將三個(gè)變量的值相加。一個(gè)由匯編啟動(dòng)文件調(diào)用用戶C程序的工程intaddxyz(inta,intb,intc){ intsum=0; sum=a+b+c; returnsum;}li4_14_ASM_CALL_C2第4章基于ARMCortexM3IP核的程序設(shè)計(jì)--匯編調(diào)用C函數(shù)(C工程不講)2025/11/28例4.14C工程構(gòu)建舉例。在匯編啟動(dòng)文件startup.s文件中編寫系統(tǒng)復(fù)位過程Reset_Handler,調(diào)用C語(yǔ)言編寫的main()函數(shù),以main()函數(shù)作為工程的入口。該工程中main()函數(shù)代碼如下:externintaddxy(inta,intb);intmain(void){ inta=1; intb=2; intc; c=addxy(a,b); return0;}main函數(shù)入口的工程構(gòu)建1110_asm_call_c1第4章基于ARMCortexM3IP核的程序設(shè)計(jì)--匯編調(diào)用C函數(shù)2025/11/28在匯編工程的主調(diào)匯編程序中,使用IMPORT聲明要調(diào)用的C函數(shù);C函數(shù)中不需要做任何聲明注意參數(shù)傳遞遵循相關(guān)標(biāo)準(zhǔn):R0,R1,R2,R3作為C函數(shù)傳遞的前4個(gè)參數(shù),若還有更多參數(shù),需通過堆棧傳遞…STACK_TOP EQU 0x20005000

IMPORT fun1 AREA RESET, CODE DCD STACK_TOP DCD start ENTRY start mov r0,5 LDR R10,=fun1 BLX R10deadloop B deadloop ENDintfun1(intn){

inti,sum=0; for(i=0;i<=n;i++) { sum=sum+i; } returnsum;}

問題描述:在匯編工程的匯編程序中,聲明一個(gè)外部C函數(shù),實(shí)參按相關(guān)標(biāo)準(zhǔn),C函數(shù)實(shí)現(xiàn)累加和,其中n由r0傳遞。目前函數(shù)完成:1+2+……5

1110_asm_call_c2第4章基于ARMCortexM3IP核的程序設(shè)計(jì)--匯編調(diào)用C函數(shù)(不講)在匯編工程的主調(diào)匯編程序中,使用IMPORT聲明要調(diào)用的C函數(shù);C函數(shù)中不需要做任何聲明注意參數(shù)傳遞遵循相關(guān)標(biāo)準(zhǔn):R0,R1,R2,R3作為C函數(shù)砂的前4個(gè)參數(shù),若還有更多參數(shù),需通過堆棧傳遞…STACK_TOP EQU 0x20005000

IMPORT fun1 AREA RESET, CODE DCD STACK_TOP DCD start ENTRY start mov r0,1 mov r1,2 mov r2,3 mov r3,4 mov r4,10 LDR R10,=fun1 BLX R10deadloop B deadloop END#include<stdio.h>#include<string.h>#defineITM_Port8(n)(*((volatileunsignedchar*)(0xE0000000+4*n)))#defineITM_Port16(n)(*((volatileunsignedshort*)(0xE0000000+4*n)))#defineITM_Port32(n)(*((volatileunsignedlong*)(0xE0000000+4*n)))#defineDEMCR(*((volatileunsignedlong*)(0xE000EDFC)))//DebugExceptionandMonitorControlRegister,DEMCR#defineTRCENA0x01000000struct__FILE{inthandle;};FILE__stdout;FILE__stdin;intfputc(intch,FILE*f){ if(DEMCR&TRCENA) { while(ITM_Port32(0)==0); ITM_Port8(0)=ch; } return(ch);}intfun1(intn1,intn2,intn3,intn4,intn5){ printf("\nn1=%d",n1); printf("\nn2=%d",n2); printf("\nn3=%d",n3); printf("\nn4=%d",n4); printf("\nn5=%d",n5); intsum=0; sum=n1+n2+n3+n4+n5; printf("\nsum=%d",sum); returnsum;}只能傳4個(gè)參數(shù)!

問題描述:在匯編工程的匯編程序中,聲明一個(gè)外部C函數(shù),實(shí)參按相關(guān)標(biāo)準(zhǔn),C函數(shù)實(shí)現(xiàn)四個(gè)參數(shù)相加。---sum=1+2+3+4=10

第4章基于ARMCortexM3IP核的程序設(shè)計(jì)---C與匯編混合編程典型的開發(fā)流程---Cortex‐M3權(quán)威指南---第十章Cortex-M3的低層編程

ARM架構(gòu)過程調(diào)用標(biāo)準(zhǔn)AAPCS

C程序內(nèi)嵌匯編代碼

C程序調(diào)用匯編過程

匯編程序調(diào)用C函數(shù)

C與匯編程序變量互訪

在C和匯編混合編程的工程中,經(jīng)常需要在兩種語(yǔ)言之間共享數(shù)據(jù)。這通常涉及到在C和匯編之間傳遞變量或訪問共享的內(nèi)存區(qū)域。C與匯編程序變量互訪使得兩種語(yǔ)言能夠無縫地協(xié)同工作。它允許開發(fā)者在C代碼中定義變量,并在匯編代碼中直接訪問這些變量;或者在匯編代碼中定義變量,并在C代碼中讀取或修改這些變量的值。這種互訪能力極大地提高了混合編程的靈活性和效率。下面分兩種情況進(jìn)行介紹:匯編調(diào)C文件中的變量,C調(diào)用匯編文件中的變量。第4章基于ARMCortexM3IP核的程序設(shè)計(jì)--匯編訪問C中全局變量*.cintc_var=1;//定義全局變量*.asmIMPORTc_var;獲取c_var的地址,讀取變量LDRR0,c_varLDRR1,[R0];寫入變量c_varSTRR1,[R0]匯編訪問C文件中的變量匯編文件訪問C文件中的變量其具體方法:(1)在C文件中定義全局變量var;(2)在匯編程序中用IMPORT引入變量var;(3)使用偽指令LDR獲取變量var變量的地址;(4)使用指令LDR獲取變量var的值。1112_Asm_Access_CVariables1第4章基于ARMCortexM3IP核的程序設(shè)計(jì)--匯編訪問C中全局變量(C工程不講)在C工程的主調(diào)C程序中,定義全局變量;用EXTERN聲明一個(gè)匯編過程;在匯編過程中使用IMPORT聲明要使用的C中的外部變量;用EXPORT聲明匯編中定義的過程可以被外部訪問…#include<stdio.h>#include<string.h>#defineITM_Port8(n)(*((volatileunsignedchar*)(0xE0000000+4*n)))#defineITM_Port16(n)(*((volatileunsignedshort*)(0xE0000000+4*n)))#defineITM_Port32(n)(*((volatileunsignedlong*)(0xE0000000+4*n)))#defineDEMCR(*((volatileunsignedlong*)(0xE000EDFC)))//DebugExceptionandMonitorControlRegister,DEMCR#defineTRCENA0x01000000struct__FILE{inthandle;};FILE__stdout;FILE__stdin;intfputc(intch,FILE*f)//???????{ if(DEMCR&TRCENA) {while(ITM_Port32(0)==0); ITM_Port8(0)=ch; } return(ch);}externintadd_v(intaddnum);intglobvar=3;intmain(){ intchangedglobvar; intaddn=255; printf("globvar=%d",globvar); changedglobvar=add_v(addn); printf("\nchangedglobvar=%d",changedglobvar); return(0);}AREAEX4_57,CODE,READONLYEXPORTadd_vIMPORTglobvaradd_v mov r10,r0 LDR R1,=globvarLDR R0,[R1]ADD R0,R0,R10STR R0,[R1]MOV PC,LREND

問題描述:在C工程中定義一個(gè)全局變量globvar=3,定義一個(gè)外部匯編過程intadd_v(intaddnum),實(shí)現(xiàn)globvar+addnum目前完成:3+255=2581112_Asm_Access_CVariables2第4章基于ARMCortexM3IP核的程序設(shè)計(jì)--匯編訪問C中全局變量(C工程不講)在C工程的主調(diào)C程序中,定義全局變量;用EXTERN聲明一個(gè)匯編過程;在匯編過程中使用IMPORT聲明要使用的C中的外部變量;用EXPORT聲明匯編中定義的過程可以被外部訪問…#include<stdio.h>#include<string.h>#defineITM_Port8(n)(*((volatileunsignedchar*)(0xE0000000+4*n)))#defineITM_Port16(n)(*((volatileunsignedshort*)(0xE0000000+4*n)))#defineITM_Port32(n)(*((volatileunsignedlong*)(0xE0000000+4*n)))#defineDEMCR(*((volatileunsignedlong*)(0xE000EDFC)))//DebugExceptionandMonitorControlRegister,DEMCR#defineTRCENA0x01000000struct__FILE{inthandle;};FILE__stdout;FILE__stdin;intfputc(intch,FILE*f)//???????{ if(DEMCR&TRCENA) {while(ITM_Port32(0)==0); ITM_Port8(0)=ch; } return(ch);}intn[]={10,9,8,7,6,5,4,3,2,1}externintmax_v(int*num);intmain(){ printf("TheOriginalNum:\n"); for(inti=0;i<10;i++) {printf("n[%d]=%d",i,n[i]); } max_v(n); printf("\nTherearrangedNum:\n"); for(inti=0;i<10;i++) {printf("n[%d]=%d",i,n[i]); } return(0);}AREAMAX,CODE,READONLY

EXPORTmax_vIMPORTnNEQU10max_v LDR R0,=n MOV R1,#0 MOV R2,#0 LOOPI ADD R3,R0,R1,LSL#2 ;ía?-?·ê×μ??··?è?R3 MOV R4,R3 ADD R2,R1,#1 MOV R5,R4 LDR R6,[R4] LOOPJ ADD R5,R5,#4 LDR R7,[R5] CMP R6,R7 BLT NEXT ;SWP R7,R6,[R5] ldr r7,[r5] str r6,[r5] MOV R6,R7 NEXT ADD R2,R2,#1 CMP R2,#N BLT LOOPJ ;SWP R7,R6,[R3] ldr r7,[r3] str r6,[r3] ADD R1,R1,#1 CMP R1,#N-1 BLT LOOPI BX LR END

問題描述:在C工程中定義一個(gè)全局變量intn[]={10,9,8,7,6,5,4,3,2,1},定義一個(gè)外部匯編過程max_v(int*num),實(shí)現(xiàn)排序li4_15_ASM_CALL_Cvariable2025/11/28例4.15匯編訪問C文件中變量舉例。在C文件中定義一個(gè)全局變量globvar并賦初值,定義一個(gè)外部匯編過程intaddxy(inta,intb),實(shí)現(xiàn)a+b+globvar。第4章基于ARMCortexM3IP核的程序設(shè)計(jì)--匯編訪問C中全局變量匯編中調(diào)用C中的變量globvar第4章基于ARMCortexM3IP核的程序設(shè)計(jì)--C調(diào)用匯編文件中的變量C調(diào)用匯編文件中的變量具體方法:(1)在匯編文件中,用偽指令“EXPORT”定義變量x1;(2)C文件中用extern引入該變量;(3)在C文件中用變量名訪問該變量。*.cexternintx1;intmain(void){ inta=1; a=a+x1; return0;}EXPORT x1 AREAMYDATA,DATA,READONLYx1 dcd0xFF endC調(diào)用匯編文件中的變量舉例li4_16_C_CALL_ASMVariable概覽

C函數(shù)調(diào)用匯編過程

C函數(shù)中內(nèi)嵌匯編指令匯編調(diào)用C函數(shù)匯編訪問C中全局變量典型的開發(fā)流程第4章基于ARMCortexM3IP核的程序設(shè)計(jì)典型的開發(fā)流程---Cortex‐M3權(quán)威指南---第十章Cortex-M3的低層編程

在開發(fā)基于CM3的應(yīng)用程序時(shí),常常有多種源程序和庫(kù),有些是自己寫的,有些是別人已經(jīng)寫好的(尤其是底層的軟件)。上述這些開發(fā)工具,在代碼生成的流程都差不離。對(duì)于最基本的應(yīng)用,也至少需要C編譯器,連接器以及二進(jìn)制文件處理工具。如果使用的是ARM的工具,如RVDS或RealView編譯器工具(RVCT),則它們的流程如下圖所示。其中的“分散加載腳本”是可選的,但是當(dāng)存儲(chǔ)器映射變得比較復(fù)雜時(shí),則需要它。圖

使用ARM工具鏈時(shí)的典型開發(fā)流程第4章基于ARMCortexM3IP核的程序設(shè)計(jì)---典型的開發(fā)流程

本章為提供了若干匯編寫的例子,在實(shí)際應(yīng)用中,這些程序都會(huì)用C寫。但是以匯編的方式呈現(xiàn),有助于讓讀者更深更好地理解CM3的工作內(nèi)幕,以便在以后用C開發(fā)時(shí)心里更有底。這里給的程序都用ARM的匯編器(armasm)來匯編,其它工具可能對(duì)語(yǔ)法格式有些不同的要求。

而且實(shí)際上,開發(fā)工具幾乎都會(huì)把啟動(dòng)工作為你做好,讓你根本不用去想還有啟動(dòng)代碼的事(不過,這也妨礙了我們學(xué)習(xí)得更深入)。下面,就隆重請(qǐng)出本書第一個(gè)完整的示例程序(請(qǐng)參考向量表來閱讀)第4章基于ARMCortexM3IP核的程序設(shè)計(jì)---典型的開發(fā)流程STACK_TOPEQU0x20002000 ;SP初始值,常數(shù) AREA|HeaderCode|,CODE DCDSTACK_TOP ;棧頂(MSP的) DCDStart ;復(fù)位向量 ENTRY ;指示程序從這里開始執(zhí)行Start ;主程序開始 ;初始化寄存器 MOVr0,#10 ;加載循環(huán)變量的初值 MOVr1,#0 ;初始化運(yùn)算結(jié)果的值 ;計(jì)算10+9+8+...+1loop ADDr1,r0;R1+=R0 SUBSr0,#1 ;R0自減,并且根據(jù)結(jié)果更新標(biāo)志(有”S”后綴) BNEloop ;if(R0!=0)gotoloop; ;現(xiàn)在,運(yùn)算結(jié)果在R1中deadloop Bdeadloop;工作完成后,進(jìn)入無窮循環(huán) END;標(biāo)記文件結(jié)束第4章基于ARMCortexM3IP核的程序設(shè)計(jì)---典型的開發(fā)流程

重溫一下我們的第一個(gè)例子:在我們做到程序連接這一步時(shí),我們手工指定了讀/寫區(qū)的位置。那么我們?cè)撊绾伟褦?shù)據(jù)放到那里呢?正點(diǎn)的解決方法是:在匯編源文件中定義一個(gè)相應(yīng)的數(shù)據(jù)區(qū)。讓連接器把數(shù)據(jù)區(qū)中的內(nèi)容分派到我們指定的位置——從0x20000000(SRAM區(qū)的起始)處開始的內(nèi)存。第4章基于ARMCortexM3IP核的程序設(shè)計(jì)---典型的開發(fā)流程STACK_TOPEQU0x20002000 ;SP初始值,常數(shù) AREA|HeaderCode|,CODE DCDSTACK_TOP ;棧頂(MSP的) DCDStart ;復(fù)位向量 ENTRY ;指示程序從這里開始執(zhí)行Start MOVr0,#10 ;加載循環(huán)變量的初值 MOVr1,#0 ;初始化運(yùn)算結(jié)果的值loop ADDr1,r0 ;R1+=R0 SUBSr0,#1 ;R0自減,并且根據(jù)結(jié)果更新標(biāo)志(有”S”后綴) BNEloop ;if(R0!=0)gotoloop; LDRr0,=MyData1 STRr1,[r0] ;把結(jié)果存入MyData1deadloop Bdeadloop ;工作完成后,進(jìn)入無窮循環(huán) AREA|HeaderData|,DATA ALIGN4 MyData1 DCD0 ;Destinationofcalculationresult MyData2 DCD0 END;文件結(jié)束標(biāo)記在連接階段,連接器要把DATA區(qū)放入讀/寫存儲(chǔ)器中,因此MyData1的地址就將是我們指定的0x2000_0000。第4章基于ARMCortexM3IP核的程序設(shè)計(jì)---典型的開發(fā)流程本次課內(nèi)容就介紹完了,同學(xué)們,再見!在CM3上編程,既可以使用C也可以使用匯編。可能還有其它語(yǔ)言的編譯器,但是大多數(shù)人還是會(huì)在C與匯編的世界里游弋。C與匯編都有尺短寸長(zhǎng),不能互相取代。使用C能開發(fā)大型程序,而匯編則用于執(zhí)行特種任務(wù)。

TheCortex-M3canbeprogrammedusingei

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論