《TMS320C3X系列-DSP原理與開發(fā)技術》課件第4章_第1頁
《TMS320C3X系列-DSP原理與開發(fā)技術》課件第4章_第2頁
《TMS320C3X系列-DSP原理與開發(fā)技術》課件第4章_第3頁
《TMS320C3X系列-DSP原理與開發(fā)技術》課件第4章_第4頁
《TMS320C3X系列-DSP原理與開發(fā)技術》課件第4章_第5頁
已閱讀5頁,還剩156頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

第4章TMS320C3x匯編語言指令

與命令文件

4.1匯編偽指令4.2TMS320C3x匯編語言指令4.3公共目標文件格式4.4命令文件

本章小結

思考題和習題4.1匯?編?偽?指?令

匯編偽指令提供程序數據,控制匯編過程,用戶可以用它們來完成以下任務:將代碼和數據匯編到特定的段(對于段的概念見后續(xù)內容);為初始化的便利保留存儲器的空間;控制列表的形式;存儲器初始化;匯編條件塊;定義全局變量;指定匯編器可以獲得宏的特定庫;檢查符號調試信息。

C3x常用的匯編偽指令如下:.end ;程序結束標志.float ;定義1個或多個單精度浮點常數.set ;定義1個或多個常數或符號.global ;定義全局變量或數據塊.space ;編譯時自動產生的空行數.word ;定義整型數據或數組.text ;程序代碼段.bss ;為初始化變量保留存儲空間段

.data ;初始化數據段

.sect ;已初始化可重定位的段

.usect ;未初始化具有絕對地址的段當然還有其它的一些不常用的偽指令,可查閱TI公司的相關手冊。4.2TMS320C3x匯編語言指令

4.2.1數據傳輸指令

TMS320C3x支持13條數據傳輸指令,可以實現寄存器之間、存儲器之間以及寄存器與存儲器之間的數據傳輸和存儲。這些指令的指令格式、用途、操作及其說明如表4.1所示。指令中的源操作數可通過寄存器尋址、直接尋址、間接尋址(disp=0~255,IR0,IR1)和立即尋址這四種通用的尋址方式給出。表4.1數據傳輸指令例4.1浮點指數的裝載。如:LDER0,R6指令執(zhí)行前 指令執(zhí)行后

R0=0200056F30 R0=0200056F30

R6=0857682386 R6=0257682386例4.2條件裝載浮點數。如:LDFCR1,R2指令執(zhí)行前 指令執(zhí)行后

R1=2CFF789634 R1=2CFF789634

R2=5F234B6780 R2=2CFF789634

C=1

C=1例4.3裝載整型數。如:LDI*++AR1(IR1),R8指令執(zhí)行前 指令執(zhí)行后

R8=1000h R8=123h

AR1=809800h AR1=809805h

IR1=5h IR1=5h

(809805h)=123h (809805h)=123h例4.4裝載數據頁指針。如:LDP@809806h,DP指令執(zhí)行前 指令執(zhí)行后

DP=60h

DP=80h例4.5彈出堆棧。如:POPR3指令執(zhí)行前 指令執(zhí)行后

R3=123h R3=5h

SP=09802h SP=809801h

(809802h)=5h (809802h)=5h例4.6壓入堆棧。如:PUSHR3指令執(zhí)行前 指令執(zhí)行后

R3=123h

R3=123h

SP=809802h

SP=809803h

(809803h)=5h

(809803h)=123h例4.7存儲整數。如:STIR4,@9700h指令執(zhí)行前 指令執(zhí)行后

R4=123h R4=123h

DP=80h DP=80h

(809700h)=5h (809700h)=123h4.2.2二操作數指令所謂的二操作數,是指源操作數和目的操作數。源操作數可以通過寄存器尋址、直接尋址、間接尋址和立即尋址等尋址方式給出,而目的操作數總是在寄存器內。這些指令可完成整數和浮點數高精度運算和處理,有些指令還可完成邏輯運算和處理。TMS320VC33的二操作數指令共35條,表4.2列出了二操作數指令的指令格式、用途、格式操作及其說明等表4.2二操作數指令上述35條指令可以分為下面幾個部分:

(1)加法指令:ADDC、ADDF、ADDI;

(2)減法指令:SUBB、SUBC、SUBF、SUBI、SUBRB、SUBRF、SUBRI;

(3)乘法指令:MPYI、MPYF;

(4)邏輯運算指令:AND、ANDN、OR、NOT、XOR;

(5)移位指令:ASH、LSH、ROL、ROLC、ROR、RORC;

(6)比較指令:CMPI、CMPF;

(7)取絕對值指令:ABSI、ABSF;

(8)取反指令:NEGB、NEGF、NEGI;

(9)變換指令:FIX、FLOAT;

(10)其他:NORM、TSTB、RND。

例4.8加法運算。如:ADDIR0,R6指令執(zhí)行前 指令執(zhí)行后

R0=123h R0=123h

R6=35h R6=158h例4.9帶借位的減法。如:SUBB*AR5++(4),R0指令執(zhí)行前 指令執(zhí)行后

R0=124h R0=120h

AR5=809800h AR5=809804h

C=1

C=1

(809800h)=3h

(809800h)=3h

例4.10條件減法。如:SUBC3000,R0指令執(zhí)行前 指令執(zhí)行后

R0=7D0h(2000) R0=FA0h例4.11乘法運算。如:MPYIR1,R3指令執(zhí)行前 指令執(zhí)行后

R1=5h R1=5h

R3=6h R3=1Eh例4.12邏輯運算。如:ANDN@980Ch,R0指令執(zhí)行前 指令執(zhí)行后

R0=7D0h R0=6D0h

DP=80h DP=80h

(80980CHh)=123h (80980CHh)=123h例4.13移位指令。如:ASHR1,R0指令執(zhí)行前 指令執(zhí)行后

R1=FFFFFFFBh(-5) R1=FFFFFFFBh(-5)

R0=123h R0=9h例4.14比較指令。如:CMPIR1,R0指令執(zhí)行前 指令執(zhí)行后

R0=5h R0=5h

R1=8h R1=8h

N=0

N=1

C=0

C=1例4.15取反指令。如:NEGI200,R0指令執(zhí)行前 指令執(zhí)行后

R0=5h R0=FFFFFF38h(-200)4.2.3三操作數指令與二操作數指令不同的是,三操作數指令的源操作數有兩個。源操作數的尋址方式既可以是寄存器尋址,也可以是間接尋址,而目的操作數只能通過寄存器尋址得到。對于整數運算來說,寄存器尋址可以利用任意CPU寄存器,而對浮點數來說,只能使用R0~R7。若浮點數采用間接尋址的方式,立即數給出的偏移量只能用0或1,超出范圍可用索引寄存器(IR0、IR1)給出。TMS320VC33的三操作數指令一共有17條,內容涉及加法、減法、乘法、邏輯運算、移位以及比較指令等,表4.3列出了三操作數指令的指令格式、用途、格式操作及其說明等。表4.3三操作數指令例4.16三操作數的加法指令。如:ADDC3R7,*AR5++(IR0),R6指令執(zhí)行前 指令執(zhí)行后

R7=125h R7=125h

AR5=809800h AR5=809810h

IR0=10 IR0=10

R6=35h R6=626h

C=1 C=1

(809800h)=500h (809800h)=500h例4.17三操作數的算術移位指令。如:ASH3R7,*AR5++(IR0),R6指令執(zhí)行前 指令執(zhí)行后

R7=FFFFFFFBh(-5) R7=FFFFFFFBh

AR5=809800h

AR5=809810h

IR0=10

IR0=10

R6=35h

R6=FFFFFFFCh

(809800h)=FFFFFF9Ch (809800h)=FFFFFF9Ch例4.18三操作數的邏輯移位指令。如:LSH3R7,*AR5++(IR0),R6指令執(zhí)行前 指令執(zhí)行后

R7=FFFFFFFBh(-5) R7=FFFFFFFBh

AR5=809800h

AR5=809810h

IR0=10

IR0=10

R6=35h

R6=07FFFFFCh

(809800h)=FFFFFF9Ch (809800h)=FFFFFF9Ch4.2.4流程控制指令所謂流程控制指令,是指改變程序運行路徑的指令,如塊重復、跳轉、子程序調用、陷阱和中斷等。包括TMS320VC33在內的TMS320C3x和C4x系列的DSP提供了靈活和強大的流程控制指令和控制方法,極大地方便了程序的設計。這些指令的指令格式、用途、格式操作及其說明等如表4.4所示。表4.4流程控制指令續(xù)表

1.三種類型的跳轉指令

1)標準跳轉指令標準跳轉指令包括重復、調用、返回和陷阱,遇到標準跳轉指令時,程序立即發(fā)生轉移。例4.19標準跳轉指令。如:BR80h指令執(zhí)行前 指令執(zhí)行后

PC=123h

PC=80h

2)條件跳轉指令條件跳轉指令是指當條件滿足時可使程序發(fā)生轉移的指令,而跳轉條件是由前一條指令的執(zhí)行結果決定的,通常比較指令和位測試指令的執(zhí)行都會影響條件標志位。TM320C3x系列DSP有20個條件代碼,可用于任何條件分支指令。這些條件包括有符號數和無符號數與0的比較,這種比較基于各個條件標志的狀態(tài)。所有無條件指令中都有后綴“U”,以表示無條件跳轉。狀態(tài)寄存器ST中有七個條件標志位,可提供算術和邏輯指令操作結果的有關信息,下面的兩個條件之一可對這些標志位產生影響:①目的寄存器是擴展精度寄存器R0~R7之一;②如果指令是比較指令之一(CMPF、CMPF3、CMPI、CMPI3、TSTB、TSTB3),則將根據CPU寄存器的值修改狀態(tài)寄存器中的標志位。另外,影響條件標志的指令有:比較和位測試等不存儲結果的指令,產生了下溢出或上溢出的算術運算指令,以及其它一些需要將結果存儲到寄存器中的浮點、整型和邏輯操作指令。除了狀態(tài)寄存器中的條件標志外,還有一些其它用于跳轉或分支指令的條件,這些條件可用于取代流程控制指令中的“cond”,表4.5列出了這些條件所屬的類型、采用的助記符、含義及其與狀態(tài)寄存器ST中標志位的對應關系,表中也包括了狀態(tài)寄存器中的部分標志位。表中所述的下溢出和上溢出分別指超過了DSP所能表示的最小數和最大數。表4.5用于流程控制的條件標志例4.20條件跳轉指令。如:BCR1指令執(zhí)行前 指令執(zhí)行后R1=125h R1=125hPC=809800h PC=125hC=1 C=1例4.21條件跳轉指令。如:CMPIR1,R2DBGTAR2,R4指令執(zhí)行前 指令執(zhí)行后R1=125h R1=125hR2=543h R2=543hAR2=8h AR2=7hR4=897h R4=897hPC=809900h PC=897h例4.22中斷返回指令。如:RETIZ指令執(zhí)行前 指令執(zhí)行后PC=125h PC=567hSP=809900h SP=8098FFhZ=1 Z=1(809900h)=567h (809900h)=80h

3)延遲跳轉指令與前面的指令不同的是,當跳轉條件滿足時延遲跳轉指令并不立即生效,而是在執(zhí)行完緊跟其后的三條指令后再進行程序的轉移。常見的延遲跳轉指令有:BcondD、BRD、DBcondD,值得注意的是延遲跳轉指令后面的三條指令不能出現跳轉、調用、返回、比較、循環(huán)等操作。例4.23延遲跳轉指令。 指令執(zhí)行前指令執(zhí)行后BRD?80h PC=123hPC=124hLDI1,R1 PC=124hPC=125hSTIR1,*AR1 PC=125hPC=126hADDI*AR1,R2 PC=126hPC=80hNOP例4.24不正確的延遲跳轉指令。

BZDLOOP1NOPNOPBRLOOP2?;該指令位置不對,“BZDLOOP1”后三條指令內不能出現跳轉指令

NOPNOP

2.子程序調用指令調用和陷阱提供了執(zhí)行一個子程序或函數的方法。在改變PC的內容之前,CALL、CALLcond和TRAPcond指令先把PC值推入堆棧,在使用RETScond或RETIcond指令時,堆??商峁┓祷亍ALL占4個指令周期,而CALLcond和TRAPcond占5個指令周期。

(1)?CALL指令將下一個PC值推入堆棧并且將src操作數放入PC,其中src是一個24位的立即數。

(2)?CALLcond指令與CALL指令類同,但只有當規(guī)定的條件為真時才執(zhí)行,另外,CALLcond指令中的src是PC相對尋址或寄存器尋址方式。

(3)?TRAPcond也是一個條件跳轉指令,只有當規(guī)定的狀態(tài)為真時才執(zhí)行,且執(zhí)行時:①中斷被禁止,ST的GIE位寫0;②下一個PC值存入堆棧;③從陷阱矢量表的某一個指定單元中檢索出相應的向量并且加載到PC中。這個特殊地址由指令中的陷阱數值來確認。從功能上講,調用和陷阱完成相同的功能(即一個子函數被調用或執(zhí)行,然后返回調用函數),只是陷阱的優(yōu)點在于,當執(zhí)行陷阱子程序時中斷被自動禁止,而且可以使用陷阱間接地調用函數。例4.25子程序調用。

AA:LDI3H,R1

LDI3H,R4

CALLAA

指令執(zhí)行前 指令執(zhí)行后

PC=809800h

PC=809801h PC=809801h

PC=809802h

PC=809802h PC=809800h

SP=7h SP=8h

(8h)=809803h例4.26條件陷阱。如:TRAPC5指令執(zhí)行前 指令執(zhí)行后

PC=125h PC=18h

SP=809900h SP=809901h

C=1 C=0陷阱矢量表5對應的向量=18h (809901h)=126h

3.重復操作指令重復方式包括單條指令的重復執(zhí)行和一段程序的重復執(zhí)行,這些指令對實現無開銷的循環(huán)特別重要,同時也簡化了編程。利用重復方式能夠以盡可能短的時間來執(zhí)行程序代碼。

TMS320C3x的重復方式允許實現過零循環(huán)。TMS320C3x提供了兩條支持過零循環(huán)的指令:塊重復指令RPTB和單條語句的重復指令RPTS。RPTB允許一個程序塊被重復執(zhí)行規(guī)定的次數;RPTS允許對單條指令重復執(zhí)行規(guī)定的次數,并且只需一次取指,這就有效地減少了總線的擁擠。用于重復控制的寄存器有三個,分別是重復起始地址寄存器RS、重復結束地址寄存器RE和重復計數寄存器RC,它們都是CPU寄存器。

1)重復方式初始化狀態(tài)寄存器中的重復方式標志位RM對于RPTB和RPTS的操作是非常重要的。如果RM=0,則不進行重復取指;如果RM=1,則進行重復取指。另外,需要說明的是,狀態(tài)寄存器中還有一個標志位S,S位對用戶是隱含的,不能被編程,但對充分描述RPTB和RPTS的操作是必要的。如果RM=1且S=0,則執(zhí)行的是RPTB,程序從存儲器中取指;如果S=1和RM=1,則執(zhí)行的是RPTS,第一次從存儲器中取指,以后從寄存器中取指。重復方式的正確操作需要正確地初始化以上所有寄存器和狀態(tài)寄存器。

RPTB初始化:當執(zhí)行指令RPTBsrc時,CPU按以下步驟操作:

(1)?PC+1→RS,將程序塊的起始地址裝入RS;

(2)?src→RE,將src裝入RE(程序塊的結束地址),其中src含有24位地址值;

(3)?1→RM,表示是重復操作方式;

(4)?0→S位,表明這是塊重復操作方式。程序塊的重復執(zhí)行次數是通過初始化RC寄存器來確定的。由于RPTB的執(zhí)行并不裝載PC,該寄存器必須由用戶明確地裝載。典型的塊重復操作過程如下:

LDI15,PC ;15→RC

RPTBLOOP ;LOOP→RE,PC+1→RS,1→RM,0→S在典型應用中,重復方式至少要對一個程序塊重復執(zhí)行一次,重復計數器由塊重復次數減1來裝載,所有由RPTB初始化的塊重復均可被中斷,即在塊重復過程中,可以響應中斷請求。

RPTS初始化:當執(zhí)行指令RPTSsrc時,對緊跟其后的指令重復執(zhí)行src+1次,src的含義見表4.4。執(zhí)行RPTS指令時,CPU按以下步驟操作:

(1)?PC+1→RS,將起始地址裝入RS;

(2)?PC+1→RE,將程序的結束地址裝入RE。由于這是一條單指令的重復,起始地址和結束地址是相同的;

(3)?1→RM,設置狀態(tài)寄存器用來指示操作的重復方式;

(4)?1→S位,表明這是單條指令的重復操作方式;

(5)?src→RC,將操作數src裝入RC。被RPTS初始化的單條指令的重復是不可中斷的,因為RPTS僅對指令字取指一次,若再將指令字保持在指令寄存器中以備后用,則中斷會導致指令字丟失。如果某條單指令必須是可重復的或可中斷的,則應當對這條單指令使用RPTB指令。

2)重復方式的操作過程在重復方式下,CPU要比較寄存器RE和程序計數器PC的內容,如果它們相匹配并且重復計數器非負,則重復計數器遞減,并且繼續(xù)進行處理。注意:重復計數器中裝載的值應比重復執(zhí)行的次數少1,比如RC=4,那么重復執(zhí)行的次數為5次。調整PC的詳細算法如下所述。注意:①當RC=080000000h時,產生重復的最大值,這將導致080000001h次重復;當RC=0時,產生最小重復,僅有一次;②應滿足:RE≥RS,否則代碼不會被重復,甚至RM仍然保持為1;③當寫0到重復計數器或狀態(tài)寄存器的RM位時,可以停止未執(zhí)行完的重復。例4.27RPTB操作。

LDI15,RC ;將15裝入重復計數器

RPTBENDLOOP ;重復執(zhí)行下一條指令到ENDLOP之間的程序塊,共重復16次

STLOOP ;ENDLOOP和STLOOP為標號

…ENDLOOP由于塊重復過程中需要修改程序計數器,所以其它指令就不能同時修改程序計數器。必須遵循的兩條規(guī)則是:①程序塊中的最后一條指令不能是Bcond、BR、Bdcond、CALL、CALLcond、TRAPcond、RETIcond、RETScond、IDLE、RPTB或RPTS;②從程序塊中的最后四條指令中的任何一條指令不能是BcondD、BRD或DBcondD。如果不符合這兩條規(guī)則中的任何一條,PC值就將成為不確定的。例4.28塊重復中,跳轉指令的位置不正確。

LDI 15,RC ;程序計數器裝載15

RPTB ENDLOOP ;執(zhí)行程序塊

STLOOP: ;從RTLOOP到

ENDLOOP重復執(zhí)行16次

ENDLOOP:BRLOOPS ;與規(guī)則①沖突例4.29塊重復中,延遲跳轉指令的位置不正確。

LDI15,RC ;程序計數器裝載15

RPTBENDLOOP ;執(zhí)行程序塊

STLOOP:… ;從RTLOOP到ENDLOOP重復執(zhí)行16次

BRDLOOPS;與規(guī)則②沖突

ADDF

MPYF

ENDLOOP:SUBF

RPTB是可以嵌套的,由于所有的控制是通過RS、RE、RC和ST寄存器定義的,保留和恢復這些寄存器要考慮到它們的嵌套。狀態(tài)寄存器中的RM位可以用來確定塊重復方式是否有效。例如,如果中斷服務子程序需要使用RPTB,則在另一個塊重復期間有可能發(fā)生中斷,當響應中斷后,這個中斷服務子程序首先檢測RM位。如果該位被置位,中斷服務子程序保留RS、RE、RC和ST,然后執(zhí)行中斷服務子程序中的塊重復。在返回中斷服務子程序之前,恢復RS、RE、RC和ST。如果沒有對RM置位,就沒有必要保留和恢復這些寄存器。

4.中斷

TMS320C3x支持多個內部和外部中斷,內部中斷由DMA控制器、定時器和串行口產生,外部中斷由4個外部中斷引腳~上的觸發(fā)信號產生,這種觸發(fā)信號包括電平觸發(fā)和下降沿觸發(fā)。外部中斷采用電平觸發(fā)方式時,低電平的持續(xù)時間至少要持續(xù)一個H1或H3周期,但不能超過2個H1或H3周期,否則會有多個中斷被確認。如果多個中斷在一個時鐘周期內同時發(fā)生,則按照~的優(yōu)先級順序執(zhí)行。DSP響應中斷后,狀態(tài)寄存器ST中的GIE被復位為0,使以后的中斷無效,直到GIE再次被置為1。對于采用下降沿觸發(fā)的中斷,外部管腳必須從1變?yōu)?,并且至少要保持一個H1或H3周期。與中斷有關的寄存器包括狀態(tài)寄存器ST、中斷使能寄存器IE和中斷標志寄存器IF。ST中的CPU全局中斷使能標志位GIE控制所有的CPU中斷,當GIE=1時,CPU響應中斷;GIE=0時,CPU則不響應。當外部中斷發(fā)生時,IF寄存器中相應的標志位被設置為1,當中斷被CPU或DMA響應后,相應的中斷標志位被內部中斷回答信號清零。但當中斷為電平觸發(fā)方式時應當注意到,如果中斷回答信號出現后仍然是低電平,則中斷標志位將只被清零一個周期后又被置位,這就會被誤認為又發(fā)生了一次中斷。用軟件可以對中斷標志寄存器IF進行讀或寫。向IF寄存器寫入1就把相應的中斷標志置位為1,同樣,寫入0就把相應的中斷標志位復位為0。所以,通過軟件就可觸發(fā)或消除所有的中斷。

內部中斷的操作方式與外部中斷相類似,不過所有的內部中斷請求信號的持續(xù)時間由硬件自動保證為一個H1/H3周期。

TMS320C3x允許CPU和DMA并行對中斷做出反應和處理,發(fā)生CPU中斷至少需要滿足下列2個條件:

(1)通過設置狀態(tài)寄存器的GIE控制位為1,以允許CPU中斷;

(2)設置IE寄存器中相應的控制位,以便允許某一具體的中斷發(fā)生,而且IF寄存器中相應的控制位為1。

CPU對中斷的響應過程是:

(1)?IF寄存器中相應的標志位和ST寄存器中的GIE被清零;

(2)?CPU處理已經被取指的指令;

(3)當前的PC值推入棧頂;

(4)取中斷向量并裝入PC;

(5)開始執(zhí)行中斷服務子程序的第一條指令。如果希望中斷服務子程序可被中斷,可以在進入中斷服務子程序后設置GIE=1。需要注意的是:①在執(zhí)行指令RPTS的過程中不響應中斷;②在執(zhí)行完緊跟在延遲跳轉指令后面的3條指令之前,不響應中斷;③已經完成了取指而處于譯碼、讀操作數和執(zhí)行階段的所有指令將被執(zhí)行完后才能響應中斷;④正處于取指階段的指令將被停止取指。

CPU全局中斷是否允許是由ST寄存器中的GIE位控制的,而所有的DMA中斷都是由IE寄存器的高16位和DMA全局控制寄存器中的SYNC位控制的。TMS320C3x允許CPU和DMA并行響應和處理中斷,DMA的中斷過程與CPU的中斷過程類似,圖4.1給出了CPU和DMA的中斷處理流程圖。圖4.1CPU和DMA中斷處理示意圖4.2.5互鎖指令

互鎖操作指令支持多處理器之間的通信,可有效保證信號的同步,實現多個DSP之間的高速通信和高速信號處理。這些指令的指令格式、用途、格式操作及其說明如表4.6所示。表4.6互鎖操作指令

例4.30互鎖指令。

如:LDP80??;裝入數據頁指針

LDII

@9800h,R1

;互鎖操作開始,將地址為809800h單元中的數值放入R1中

STIIR2,@9900h?;互鎖操作結束,將R2中的數值放入地址為809900h的單元中4.2.6并行指令

并行操作指令具有高度的并行操作能力,在一個指令周期內可以同時完成兩條指令的處理,但并不是任何兩條指令都可以實現并行操作,可以并行處理的指令局限于以下類型:

(1)算術運算或邏輯運算指令與存儲指令的并行,如表4.7中的第1~16行;

(2)兩條寄存器裝載指令的并行,如表4.7中的第17~18行;

(3)兩條算術運算指令的并行,如表4.7中的第19~24行;

(4)兩條存儲指令的并行,如表4.7中的第25~26行;

(5)寄存器裝載和存儲指令的并行,如表4.7中的第27行。這里所述的寄存器裝載指令是指LDI和LDF,它們的目的地址指向寄存器;存儲指令指STI和STF,它們的目的地址指向存儲器。

在并行尋址中,操作數的尋址方式只有間接尋址和寄存器尋址兩類,其中間接尋址的偏移量取值只限0或1,超出范圍用索引寄存器(IR0、IR1)表示,而寄存器的操作僅對R0~R7有效。

成對指令中的第一條指令以獨立的源語句輸入,第二條指令前必須加上兩條垂直線“||”。表4.7列出了并行指令的指令格式、格式操作及其說明。表4.7并行運行指令

續(xù)表例4.31取絕對值與存儲指令的并行。

如:ABSI*-AR5(1),R5

||STIR1,*AR1--(IR1)

指令執(zhí)行前 指令執(zhí)行后

R1=12h R1=12h

R5=54h R5=5h

AR1=809802h AR1=809800h

AR5=809901h AR5=809901h

IR1=2h

IR1=2h

(809900h)=FFFFFFFBh(-5) (809900h)=FFFFFFFBh

(809802h)=28h (809802h)=12h例4.32算術運算與存儲指令的并行。

如:ADDI3*--AR5(IR0),R3,R5

||STIR1,*AR1

指令執(zhí)行前 指令執(zhí)行后

R1=12h R1=12h

R3=9h

R3=9h

R5=54h

R5=4h

AR1=809802h AR1=809802h

AR5=809901h AR5=809800h

IR0=1h

IR0=2h

(809900h)=FFFFFFFBh(-5) (809900h)=FFFFFFFBh

(809802h)=28h (809802h)=12h例4.33邏輯運算與存儲指令的并行。

如:AND3*+AR1(IR0),R4,R7

||STIR1,*AR2

指令執(zhí)行前 指令執(zhí)行后

R1=12h R1=12h

R4=10h R4=10h

R7=54h R7=0h

AR1=809802h

AR1=809802h

AR2=809901h

AR2=809901h

IR0=1h IR0=1h

(809803h)=101h

(809803h)=101h

(809901h)=18h

(809901h)=12h例4.34移位指令與存儲指令的并行。

如:LSH3R1,*+AR1(IR0),R2

||STIR3,*AR2

指令執(zhí)行前 指令執(zhí)行后

R1=10h R1=10h

R2=56h R2=0AC0000h

R3=9h R3=9h

AR1=809802h AR1=809802h

AR2=809901h AR2=809901h

IR0=1h IR0=1h

(809803h)=0ACh

(809803h)=0ACh

(809901h)=18h

(809901h)=9h

例4.35兩條算術指令的并行。

如:MPYI3R0,R5,R1

||ADDI3*AR2,*AR1--(IR1),R2

指令執(zhí)行前 指令執(zhí)行后

R0=2h R0=2h

R1=5h R1=0Ah

R2=9h R2=656h

R5=5h R5=5h

IR1=2h IR1=2h

AR1=809907h AR1=809805h

AR2=809901h AR2=809901h

(809901h)=123h (809802h)=123h

(809907h)=533h (809901h)=533h例4.36邏輯運算與存儲指令的并行。

如:NEGI*-AR1,R1

||STIR2,*AR2++(IR0)

指令執(zhí)行前 指令執(zhí)行后

R1=2h R1=FFFFFF9Ch(-100)

R2=5h R2=5h

IR0=3h IR0=3h

AR1=809806h

AR1=809806h

AR2=809900h

AR2=809903h

(809805h)=100h

(809805h)=100h

(809900h)=456h

(809900h)=5h例4.37邏輯運算與存儲指令的并行。

如:OR3*++AR1,R1,R2

||STIR3,*AR2

指令執(zhí)行前 指令執(zhí)行后

R1=2h R1=2h

R2=5h R2=12h

R3=9h R3=9h

AR1=809800h AR1=809801h

AR2=809900h AR2=809900h

(809801h)=10h (809801h)=10h

(809900h)=456h (809900h)=9h例4.38寄存器裝載指令的并行。

如:LDI*++AR1,R1

||LDI*AR2,R2

指令執(zhí)行前 指令執(zhí)行后

R1=2h R1=10h

R2=5h R2=456h

AR1=809800h AR1=809801h

AR2=809900h AR2=809900h

(809801h)=10h (809801h)=10h

(809900h)=456h (809900h)=456h例4.39存儲指令的并行。

如:STIR1,*-AR1(IR0)

||STIR2,*AR2

指令執(zhí)行前 指令執(zhí)行后

R1=2h R1=2h

R2=5h R2=5h

IR0=5h IR0=5h

AR1=809800h AR1=809800h

AR2=809900h AR2=809900h

(8097FBh)=10h (8097FBh)=2h

(809900h)=456h (809900h)=5h4.3公共目標文件格式

匯編器和鏈接器建立的目標文件格式稱為公共目標文件格式(CommonObjectFileFormat,COFF),采用這種目標文件格式更有利于模塊化編程,應用COFF編寫程序時不必為程序代碼和變量指定地址,這給程序的編寫和移植帶來極大的好處。在實際操作時,通過建立命令文件,實現對存儲器的資源和代碼段的管理。4.3.1匯編器的作用

匯編器的作用就是將匯編語言源程序轉換成機器語言目標文件。這些目標文件都是公共目標文件格式(CommonObjectFileFormat,COFF),其主要功能如下:

(1)將匯編語言源程序匯編成一個可重新定位的目標文件(擴展名為?.obj);

(2)如果需要,則可以生成一個列表文件(擴展名為?.lst);

(3)將程序代碼分成若干個段,每個段的目標代碼都有一個SPC(段程序計數器)管理;

(4)定義和引用全局符號,需要的話還可以在列表文件后面附加一張交叉引用表;

(5)對條件程序塊進行匯編;

(6)支持宏功能,允許定義宏命令。4.3.2鏈接器的作用鏈接器的主要任務是:根據鏈接命令文件或命令文件(?.cmd文件),將一個或多個COFF目標文件鏈接起來,生成存儲器映射文件(?.map)和可執(zhí)行的輸出文件(.out文件)。在鏈接過程中,鏈接器將各個目標文件合并起來,并完成以下工作:

(1)將各個段配置到目標系統(tǒng)的存儲器;

(2)對各個符號和段進行重新定位,并給它們指定一個最終的地址;

(3)解決輸入文件之間未定義的外部引用。4.3.3公共目標文件格式的相關概念

用戶使用公共目標文件格式編寫程序時,多采用代碼段和數據段的概念,這種段稱為section。段就是指在存儲器中占據連續(xù)空間的代碼塊或數據塊,它是目標文件中的最小單位,有些資料中也將段稱為“塊”。所有的COFF目標文件都包括下面形式的段,其中前3個段為COFF目標文件最基本的段。

(1)?.text:用以定義可執(zhí)行代碼段。

(2)?.data:用以定義初始化數據段。

(3)?.bss:為未初始化的數據保留空間,未初始化的數據指運行過程中的變量,在定義時無具體內容,僅僅是為其預留一定的空間。

(4)?.sect:用以定義已初始化且有名稱的段,該段中可以含有代碼或數據,用于創(chuàng)建自定義段。當程序員想把一部分程序放在不同于.text的存儲器中時,需使用該命令,對數據也可進行同樣處理。

(5)?.usect:為未初始化且有名稱的段保留空間,與?.bss類同,但被保留的空間可以是不連續(xù)的。

(6)?.asect:用于建立具有絕對地址的有名稱的初始化段。上述6種段從是否初始化的角度來看,可以劃分為已初始化段和未初始化段。其中?.text、.data、.sect、.asect創(chuàng)建的都是已初始化的段,.bss、.usect創(chuàng)建的段屬于未初始化的段。未初始化的段在定義時沒有具體內容,已初始化的段是有具體內容的,例如?.text段含有源程序代碼,.data段是由具體數據或常數組成的。未初始化段主要用來為DSP在存儲器中保留空間,這些段中沒有實際的內容,僅僅是保留空間,程序可以在運行時利用這些空間來建立和保存變量,它們一般被分配到RAM中。建立未初始化段的命令有?.bss和?.usect。匯編器提供了若干將各種代碼和數據段與相應的段聯系的命令,匯編器是在匯編過程中建立這些段的。圖4.2給出了一個包含?.text、.data和?.bss段的目標文件。圖4.2段在存儲器中的分配情況鏈接器的一個主要功能是將段定位至目標存儲器中。在匯編器匯編形成的目標文件中,除了用?.asect命令定義的段之外,其他程序段和數據段的地址都是不確定的。確定段地址的工作一般由鏈接器來完成。由于大部分系統(tǒng)一般含有多個類型的存儲器(EPROM、RAM或FLASH等),采用段可以使用戶更有效地利用目標存儲器。所有的段都可以獨立地進行重定位,因此可以將不同的段分配到各種存儲器中。例如,可以定義一個包含已初始化的段,然后將它分配至包含EPROM的存儲器映射中。圖4.2也示出了目標文件中的段和目標系統(tǒng)中的存儲器之間的關系。4.3.4匯編器對段的處理

匯編器對段的處理功能主要是確定匯編語言程序各部分屬于哪個特定的段。匯編器有六個命令,即?.bss、.usect.、text、.data、.sect和?.asect,其中,.bss和?.usect命令創(chuàng)建的段屬于未初始化的段,.text、.data、.sect和?.asect命令則是建立已初始化段。當然,如果在程序中未用任何命令來定義,那么匯編器將把所有的程序段或數據段統(tǒng)一匯編至?.text中。

1.未初始化段命令

(1)?.bss命令的用途是為變量保留空間,格式是:

.bss符號,字數上述命令格式中的“符號”和“字數”都是不可省略的參數。符號由程序員自己定義,如“var1”、“var2”等,符號指向被保留空間中的第一個字,字數則以數字的形式指定需要保留幾個字。

例:.bssarray,100;該命令為變量array分配了100個字

(2)?.usect命令的格式如下:

符號.usect“段名”,字數

“符號”、“段名”和“字數”都是不可省略的參數,其中“段名”要用雙引號括起來,“字數”則用數字表示需要保留的字的數目?!胺枴焙汀岸蚊倍际浅绦騿T自己定義的,但“段名”的長度不能超過8個英文字符。該命令與?.bss類似,都是為變量保留空間,該空間內事先無任何內容,只是為程序運行過程中產生的變量預留了空間,但它們也有區(qū)別。如果在程序中出現了多個?.bss命令,不管該命令中的符號是否相同,匯編器都將各個?.bss命令預留的空間統(tǒng)一匯編到一個段中;但如果出現了多個?.usect命令,則要看其名稱是否一致,只有該命令中指定的“段名”相同時,才匯編到一個段中,否則,不同段名指定的空間將匯編到不同的段。

例4.40用?.usect建立不同的段。1 .text ;text段開始

2 LDIR0,R1 ;在text段中

3 ptr .usect"var1",1

4 array .usect"var1",100

5 LDIR1,R2 ;仍在text段

6 dflag .usect"var1",50

7 LDIR2,R3 ;仍在text段

8 .bssbuffer1,1

9 .bssbuffer2,10

10 vec .usect"var2",100

11 LDI@vec,R0 ;仍在text段對上述程序匯編后,共產生4個段:

①.text:包含第2、5、7、11行等4行指令的目標代碼。

②.bss:在存儲器中保留了11個字,包括第8行定義的1個字和第9行定義的10個字,其中buffer1和buffer2分別指向上述兩個字塊的第一個字。

③var1:在存儲器中為該段保留了151個字,包括第3行定義的1個字,第4行定義的100個字和第6行定義的50個字,其中符號ptr、array和dflag分別指向上述3個字塊的第一個字。

④var2:在存儲器中保留了100個字,vec指向第一個字。本例中?.text為初始化的段,其它三個為未初始化的段。匯編器在遇到?.text、.data、.sect、

.asect等初始化的段時,立即停止匯編至當前段并開始所遇到的新段的匯編,但當遇到?.bss、.usect時并不結束當前段的匯編,而只是暫時離開當前段,所以?.bss和?.usect命令可以出現在已初始化段中的任何地方,而不影響已初始化段的內容。

2.已初始化段命令

.text、.data、.sect、.asect命令建立的段為已初始化的段,已初始化段包括可執(zhí)行代碼和已初始化的數據,這些段的內容存儲在目標文件中。當程序裝入時,存放在存儲器中。它們的功能分別如下:

(1)?.text命令。此命令沒有任何參數,在匯編語言編制的源程序中單獨占一行。“text”本身就是段名,該段中含有可執(zhí)行代碼,它告訴匯編器將?.text下面的源代碼匯編到text段。匯編器可以把所有段名相同但分布在程序多處的數據或程序匯編到一個段中,完成這一有序工作的是段程序計數器(SectionProgramCounter,SPC)。初始化時,所有的SPC均置0,隨著數據或程序在段中的放置,計數器的值發(fā)生變化。在將下一段具有相同段名的可執(zhí)行代碼或數據匯編至同一段中之前,先取出相應段的SPC,隨著數據或程序地加入,SPC值發(fā)生變化。如果該段的內容原來為空,則SPC從零開始計數;如果該段的內容不為空,則SPC接著原來的計數值繼續(xù)計數,即每匯編到該段一個字,計數值加1。正是由于上述原因,.text等創(chuàng)建初始化段的命令可以在一個程序中出現多次。需要說明的是,匯編器總是假定.text是缺省的段,因此,如果在程序的開始沒有指定?.data、.sect或?.asect等初始化的段,匯編器將自動地將所遇到的代碼匯編到?.text段。

(2)?.data命令。該命令沒有任何參數,在程序中單獨占一行,“data”本身就是段名。該命令告知匯編器將?.data下面的源代碼匯編到data段,直到遇到其它已初始化的段時才停止當前段的匯編。data段一般含有?.word、.byte、.float等對常數進行初始化的命令。例4.41.data命令及用于常數初始化的常用命令。

1.data

2coff.word011h,022h,808060h

3val.word-123h

4const.byte0FCh,080h

5pai.float3.141596

6.text

7LDIR0,R2

8.end該例中coff、val、const、pai等為符號,命令后面的數據可以是一個也可以是多個。匯編后,上述符號都有一個地址,它們分別指向相應命令后面的第一個數。上述3個用于定義常數的命令的區(qū)別是:

.word定義32位的整型數

.byte定義8位的整型數

.float定義32位的單精度浮點數

該例中.end是程序的結束命令,當匯編器遇到該命令后,停止匯編。另外兩個命令建立的段為用戶自定義的段命令,其中?.asect命令建立的段具有絕對的地址,一般不建議使用。當匯編器遇到?.text或?.data或?.sect命令時,它將停止對當前段的匯編,然后將緊接著的程序代碼或數據匯編到指定的段中,直到在遇到另一條?.text、.data、.asect或?.sect命令為止。

3.自定義的段命令

自定義的段就是程序員自己建立的段。有三條命令用來建立自定義的段:.usect、.sect和?.asect。其中,.usect命令前已講及,不再贅述。

(1)?.sect命令的常用格式為

.sect“段名”

該命令中的段名是程序員自己定義的名稱,用雙引號括起來,字符長度不能超過8個字符。匯編器遇到該命令時,開始將其后的源代碼匯編到所定義的段名中。該段中或者含有可執(zhí)行的程序,類似于text段,或者含有數據,類似于data段。除了有一個專門的名稱外,該命令的用法也與?.text和?.data相類似,利用這個專門定義的名稱,程序員可以將一部分程序或數據放在不同于?.text和?.data的段中,即可以利用該命令建立自己定義的段。

(2)?.asect命令與?.sect命令類似,也是創(chuàng)建一個有名稱的段,但在段名后需要用數值給出該段在存儲器中的絕對地址。由于這種作法不利于程序的可移植性,所以很少使用?.asect命令。其格式為:

asect"段名",地址4.3.5鏈接器對段的處理

鏈接器對段的處理主要有兩個功能:首先它將COFF目標文件中的段組合起來,建立可執(zhí)行的COFF輸出模塊;其次鏈接器還為輸出段選擇存儲器地址。

為了完成上述功能,鏈接器有MEMORY和SECTIONS兩條命令。MEMORY用于定義目標系統(tǒng)的存儲器,可以定義每一段存儲器的起始地址和長度;SECTIONS用于累加器如何組合輸入段以及將輸出段放至何處。這兩條命令并不是非用不可。如果不用,鏈接器將采用缺省分配算法為各個段分配空間;如果使用,那么需要將這些命令放在命令文件(*.CMD文件)中。

1.缺省分配算法

如果不給鏈接器提供命令文件,那么鏈接器將用缺省的算法。缺省分配算法如下:

(1)假定存儲器的起始地址為0;

(2)假定全部的存儲器空間都用來分配目標代碼;

(3)將?.text分配到起始地址為0的存儲器中;

(4)將?.data分配到緊接著?.text的存儲器中;

(5)將?.bss分配到緊接著?.data的存儲器中;

(6)將自定義的段分配到緊接著?.bss的存儲器中。若自定義段多于一個,則按自定義段在文件中的先后順序存放。需要注意的是,鏈接器只是為各段指定了地址而不將程序裝入實際的存儲器。這一工作由引導程序來完成。如果輸入的目標文件有多個,則鏈接器首先將各個文件中相同段名的段組合起來,形成相應的輸出段,然后再按上述方法分配存儲器。

2.用命令文件分配存儲器

缺省分配文件將段分配到存儲器中時,必須按缺省分配算法進行。但在實際的應用中,許多情況并不一定能夠滿足缺省算法的要求,DSP的硬件系統(tǒng)中可能包含多種類型的存儲器,如SRAM、SDRAM、DRAM、ROM、EPROM、FLASH等,用戶可能將不同的段分布于不同的內存,這時就不能采用缺省算法,必須建立一個命令文件,在命令文件中用MEMORY和SECTIONS命令將各段分配至相應的存儲器中。例4.42命令文件的實例。

MEMORY

{

RAM0:origin=809800h length=400h

RAM1:origin=809c00h length=300h

RAM2:origin=800000h length=4000h

RAM3:origin=804000h length=4000h

}SECTIONS

{

.text: LOAD=RAM2

.data: LOAD=RAM3

.bss: LOAD=RAM0

.var: LOAD=RAM1

}該例通過MEMORY命令定義了RAM0、RAM1、RAM1和RAM3等4個RAM塊的起始地址和長度,它們的起始地址必須在第2章圖2.8(b)所示RAM的允許范圍內,其長度不能超過實際允許的空間。SECTIONS命令將?.text、.data、.bss、.var等4個段分配到有關的RAM中,其中?.var是程序員通過?.sect或?.usect自定義的段

3.程序重定位

匯編器對每一個段進行匯編時,都假設起始地址為0。每一個段中所有的重定位符號(標號)都是相對于0地址而言的。但實際上并不是所有的段都是以0地址作為起始地址的。因此鏈接器必須通過下面的步驟對每個段進行重定位。

(1)將段分配到存儲器,使其有合適的起始地址;

(2)調整符號值,使之與新的段地址相適應;

(3)調整重定位后符號的參考值,使之與調整后的符號值相一致。鏈接器利用重定位符號來調整符號的參考值,每次當一個重定位符號被參考時,匯編器就建立一個重定位項。利用這些重定位項,鏈接器在符號被重定位之后修改參考值。例4.43產生重定位項的代碼(TMS320C3x)。

1 .refX

200000000 .text

30000000060000000! BRX;產生一個重定位項

40000000108200002 LDI@Y,R0;產生一個重定位項

500000002060000000Y:IDLE該例中,符號X和Y都是可重定位的,X在其它模塊中定義,Y在本模塊的.text塊中定義。匯編之后,X的值為0(匯編器假定所有未定義的外部符號的值為0),而Y的值為2(相對于?.text塊的0地址)。匯編器為X和Y各產生一個重定位項。X的參考是外部參考(在列表中用!表示),Y的參考是內部定義的可重定位符號(用@表示)。鏈接之后,假定X重定位至地址100h,且.text塊重定位到起始地址200h,則Y重定位后的值為202h。鏈接器利用這兩個重定位項在目標代碼中補上這兩個參考:

60000100 BRX ;變?yōu)?0000100

08200002LDI@Y,R0 ;變?yōu)?8200002

COFF的目標文件中的每一塊都有一個重定位項目表,表中包含了塊中每一個可重定位參考的一個重定位項。鏈接器通常在使用過重定位項之后就將它去除,以防止對輸出塊再次重定位(如果目標文件被重新鏈接或被裝入)。沒有重定位項的文件就是所有地址都是絕對地址的絕對文件,如果程序員要保留重定位項,激活鏈接器的?-r選項即可。有時候某塊程序裝入到某個存儲器中但需在另一塊存儲器中運行,比如一個程序中的關鍵代碼裝在ROM中但需在更高速度的RAM中運行時就是如此,此時必須進行運行時的重定位。實現的方法很簡單,可在鏈接器的命令文件的SECTIONS中將塊分配兩次,一次設定裝入地址,另一次則設定運行地址。例如:

.text:LOAD=ROM,RUN=RAM0

4.COFF文件中的符號

COFF文件包含一個與程序中的符號信息有關的符號表,鏈接器在進行重定位時要用到這個表,調試工具也可利用這個符號表提供符號級調試。在一個模塊中定義而在另一個模塊中引用的符號稱外部符號,一般可用?.global命令來標明某一符號。在一個源模塊中,外部符號可以是參考(ref)或是定義(ref)。

定義(ref):在當前模塊中定義,在其它模塊中引用。

參考(ref):在其它模塊中定義,在當前模塊中引用。下面的代碼可說明這兩種定義:

.globalX;X在當前模塊中定義,在其它模塊中引用

.globalY;X在其它模塊中定義,在當前模塊中引用

X: LDIR0,R1;定義X

LDI@Y,R0 ;引用Y

X是一個在本模塊中定義的外部符號,可以在其它模塊中引用;Y在其它模塊中定義,在本模塊中引用。匯編器將X和Y都放在目標文件的符號表中。匯編器匯編使所有的引用與相應的定義相一致,否則將輸出一個錯誤信息,只有沒有出錯信息才能產生可執(zhí)行的目標文件。

匯編器并不對其它類型的符號產生符號表項目,因為鏈接器不需要它們。比如程序標號就不包含在符號表中,除非用?.global來說明。在對程序進行符號級調試時,有時候在符號表中包含程序中的每一個符號,這往往是很有用的,這時需在匯編時激活-s選項。

5.COFF編程舉例

本節(jié)通過一個TMS320C3x的匯編語言程序來說明基于COFF的匯編語言編程。

例4.44COFF的匯編編程(TMS320C3x)。

.text ;匯編至?.text塊

add: LDI10,AR1

LDI0,R1

aloop: ADDI*AR0++,R1

DBNZAR1,aloop

STIR1,@varl

.data ;匯編至?.data塊

ivals .word0AAh,0BBh,0CChvar2

溫馨提示

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

評論

0/150

提交評論