版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、第第2章章 ARM指令分類及其尋址方式指令分類及其尋址方式在本章中,將介紹在本章中,將介紹ARM指令分類以及各類指令對指令分類以及各類指令對應的尋址方式。應的尋址方式。22.1 ARM指令集概要介紹指令集概要介紹在本節(jié)中,將介紹在本節(jié)中,將介紹ARM指令相關的一些基本概念,指令相關的一些基本概念,包括指令的分類、指令的一般編碼格式以及包括指令的分類、指令的一般編碼格式以及ARM指令中的條件碼。指令中的條件碼。32.1.1 ARM指令的分類指令的分類ARM指令集可以分為跳轉指令、數據處理指令、指令集可以分為跳轉指令、數據處理指令、程序狀態(tài)寄存器程序狀態(tài)寄存器(PSR)傳輸指令、傳輸指令、Load
2、/Store指令、協處理器指令和異常中斷產生指令指令、協處理器指令和異常中斷產生指令6類。類。42.1.2 ARM指令的一般編碼格式指令的一般編碼格式ARM指令字長為固定的指令字長為固定的32位。一條典型的位。一條典型的ARM指指令編碼格式如下:令編碼格式如下:31 28 27 25 24 21 20 19 16 15 12 11 8 7 0其中的符號及參數說明如下。其中的符號及參數說明如下。opcode:指令操作符編碼。cond:指令執(zhí)行的條件編碼。S:決定指令的操作是否影響CPSR的值。Rd:目標寄存器編碼。Rn:包含第1個操作數的寄存器編碼。shifter_operand:表示第2個操作
3、數。5cond0 0 1opcodeS Rn Rdshifter_operand2.1.3 ARM指令的條件碼域指令的條件碼域條件碼共有條件碼共有16個,各條件碼的含義和助記符如表個,各條件碼的含義和助記符如表2.1所示??蓷l件執(zhí)行的指令可以在其助記符的擴所示??蓷l件執(zhí)行的指令可以在其助記符的擴展域加上條件碼助記符,從而在特定的條件下執(zhí)行。展域加上條件碼助記符,從而在特定的條件下執(zhí)行。參見教材P2362.2 ARM指令的尋址方式指令的尋址方式ARM指令的尋址方式有以下幾種,分別進行討論:指令的尋址方式有以下幾種,分別進行討論:數據處理指令的操作數的尋址方式。字及無符號字節(jié)的Load/Store
4、指令的尋址方式。雜類Load/Store指令的尋址方式。批量Load/Store指令的尋址方式。協處理器Load/Store指令的尋址方式。72.2.1 數據處理指令的操作數的尋址方式數據處理指令的操作數的尋址方式通常數據處理指令的格式如下所示:通常數據處理指令的格式如下所示: S , 其中的符號及參數說明如下。其中的符號及參數說明如下。:是指令助記符,如ADD表示算術加操作指令。:表示指令執(zhí)行的條件。S:決定指令的操作是否影響CPSR的值。:表示目標寄存器。:表示包含第1個操作數的寄存器。:表示第2個操作數。82.2.1 數據處理指令的操作數的尋址方式數據處理指令的操作數的尋址方式通常有下面
5、通常有下面3種格式。種格式。(1)立即數方式。(2)寄存器方式。(3)寄存器移位方式。數據處理指令操作數的具體尋址方式有下面數據處理指令操作數的具體尋址方式有下面11種。種。#, LSL #, LSL , LSR #, LSR , ASR #, ASR , ROR #, ROR , RRX92.2.2 字及無符號字節(jié)的字及無符號字節(jié)的Load/Store指令的尋址方式指令的尋址方式各種類型的各種類型的Load/Store指令的尋址方式由兩部分組指令的尋址方式由兩部分組成。一部分為一個的基址寄存器;另一部分為一個成。一部分為一個的基址寄存器;另一部分為一個地址偏移量?;芳拇嫫骺梢詾槿我粋€通用寄
6、存地址偏移量?;芳拇嫫骺梢詾槿我粋€通用寄存器;地址偏移量可以有以下器;地址偏移量可以有以下3種格式:種格式:立即數。寄存器。寄存器及一個移位常數。同樣,尋址方式的地址計算方法有如下同樣,尋址方式的地址計算方法有如下3種:種:偏移量方法。事先更新方法。事后更新方法。102.2.2 字及無符號字節(jié)的字及無符號字節(jié)的Load/Store指令的尋址方式指令的尋址方式LDR指令的語法格式如下所示:指令的語法格式如下所示: LDRB T,其中,其中,表示第表示第2個操作數的內存?zhèn)€操作數的內存地址,共有如下地址,共有如下9種格式:種格式:, #+/, +/, +/,#, #+/!, +/!, +/,#!,
7、 #+/, +/, +/,#112.2.3 雜類雜類Load/Store指令的尋址方式指令的尋址方式這里所說的雜類這里所說的雜類Load/Store指令,包括操作數為半字指令,包括操作數為半字(無符無符號數或帶符號數號數或帶符號數)數據的數據的Load/Store指令;操作數為帶符號指令;操作數為帶符號的字節(jié)數據的的字節(jié)數據的Load 指令;雙字的指令;雙字的Load/Store指令。這類指指令。這類指令的語法格式為:令的語法格式為: LDR|STRH|SH|SB|D , 其中,其中,是指令中內存單元的尋址方是指令中內存單元的尋址方式,具體有以下式,具體有以下6種格式:種格式:, #+/, +
8、/, #+/!, +/!, #+/, +/122.2.4 批量批量Load/Store指令的尋址方式指令的尋址方式一條批量一條批量Load/Store指令可以實現在一組寄存器和指令可以實現在一組寄存器和一塊連續(xù)的內存單元之間傳輸數據。其語法格式如一塊連續(xù)的內存單元之間傳輸數據。其語法格式如下:下:DM|STM !, 其中,指令中寄存器和內存單元的對應關系滿足這其中,指令中寄存器和內存單元的對應關系滿足這樣的規(guī)則,即編號低的寄存器對應于內存中的低地樣的規(guī)則,即編號低的寄存器對應于內存中的低地址單元,編號高的寄存器對應于內存中的高地址單址單元,編號高的寄存器對應于內存中的高地址單元,元,中存放地址
9、塊的最低地址值。中存放地址塊的最低地址值。132.2.4 批量批量Load/Store指令的尋址方式指令的尋址方式表示地址的變化方式,有以表示地址的變化方式,有以下下4種方式。種方式。IA (Increment After):事后遞增方式。IB (Increment Before):事先遞增方式。DA (Decrement After):事后遞減方式。DB (Decrement Before):事先遞減方式。批量批量Load/Store指令的編碼格式如下:指令的編碼格式如下:142.2.4 批量批量Load/Store指令的尋址方式指令的尋址方式1. 事后遞增方式事后遞增方式IA2. 事先遞增
10、方式事先遞增方式IB3. 事后遞減方式事后遞減方式DA4. 事先遞減方式事先遞減方式DB5. 對應于棧操作的尋址方式對應于棧操作的尋址方式152.2.5 協處理器協處理器Load/Store指令的尋址方式指令的尋址方式一條協處理器一條協處理器Load/Store指令可以在指令可以在ARM處理器和協處理處理器和協處理器之間傳輸批量數據。其語法格式如下:器之間傳輸批量數據。其語法格式如下:L ,其中,其中,表示地址的變化方式,有以下表示地址的變化方式,有以下4種格式:種格式:,#+/*4,#+/*4!,#+/*4,協處理器協處理器Load/Store指令的編碼格式如下所示。指令的編碼格式如下所示。
11、162.2.5 協處理器協處理器Load/Store指令的尋址方式指令的尋址方式1. 偏移量偏移量 ,#+/*42. 事先更新事先更新 ,#+/*4!3. 事先更新事先更新,#+/*44. 非索引非索引 ,17第第3章章 ARM指令集介紹指令集介紹在本章中,將詳細介紹各在本章中,將詳細介紹各ARM指令,并給指令,并給出一些典型的出一些典型的ARM功能代碼段。功能代碼段。193.1 ARM指令集指令集ARM指令集可以分為指令集可以分為6類,即跳轉指令、數據處理類,即跳轉指令、數據處理指令、程序狀態(tài)寄存器指令、程序狀態(tài)寄存器(PSR)傳輸指令、傳輸指令、Load/Store指令、協處理器指令和異常
12、中斷產生指指令、協處理器指令和異常中斷產生指令。令。為了更清楚地描述這些指令,將一些大類的指令進為了更清楚地描述這些指令,將一些大類的指令進一步分為幾個小類分別講述。一步分為幾個小類分別講述。203.1.1 跳轉指令跳轉指令在在ARM中,有兩種方式可以實現程序的跳轉:一種是跳轉中,有兩種方式可以實現程序的跳轉:一種是跳轉指令;另一種是直接向指令;另一種是直接向PC寄存器寄存器(R15)中寫入目標地址值。中寫入目標地址值。在在ARM版本版本5以前的體系中,傳送到以前的體系中,傳送到PC寄存器中的目標地寄存器中的目標地址值的低兩位址值的低兩位bits1:0被忽略,跳轉指令只能在被忽略,跳轉指令只能
13、在ARM指令指令集中執(zhí)行,即程序不能從集中執(zhí)行,即程序不能從ARM狀態(tài)切換到狀態(tài)切換到Thumb狀態(tài)。狀態(tài)。非非T系列版本系列版本5的的ARM體系不含體系不含Thumb指令,當程序試圖切指令,當程序試圖切換到換到Thumb狀態(tài)時,將產生未定義指令異常中斷。狀態(tài)時,將產生未定義指令異常中斷。ARM的跳轉指令可以從當前指令向前或向后的跳轉指令可以從當前指令向前或向后32MB的地址空的地址空間跳轉。這類跳轉指令有以下間跳轉。這類跳轉指令有以下4種。種。B:跳轉指令。BL:帶返回的跳轉指令。BLX:帶返回和狀態(tài)切換的跳轉指令。BX:帶狀態(tài)切換的跳轉指令。213.1.1 跳轉指令跳轉指令1. B(跳轉指
14、令跳轉指令)及及BL(帶返回的跳轉指令帶返回的跳轉指令)2. BLX(1) 3. BLX(2)4. BX指令指令223.1.2 數據處理指令數據處理指令數據處理指令又可大致分為數據處理指令又可大致分為3類:數據傳送指令,類:數據傳送指令,如如MOV;算術邏輯運算指令,如;算術邏輯運算指令,如ADD、SUB和和AND等;比較指令,如等;比較指令,如TST。數據處理指令包括以下指令。數據處理指令包括以下指令。MOV:數據傳送指令。MVN:數據求反傳送指令。CMP:比較指令。CMN:基于相反數的比較指令。TST:位測試指令。TEQ:相等測試指令。ADD:加法指令。SUB:減法指令。233.1.2 數
15、據處理指令數據處理指令RSB:逆向減法指令。ADC:帶位加法指令。SBC:帶位減法指令。RSC:帶位逆向減法指令。AND:邏輯與操作指令。BIC:位清除指令。EOR:邏輯異或操作指令。ORR:邏輯或操作指令。243.1.3 乘法指令乘法指令ARM有兩類乘法指令:一類為有兩類乘法指令:一類為32位的乘法指令,位的乘法指令,即乘法操作的結果為即乘法操作的結果為32位;另一類為位;另一類為64位的乘法指位的乘法指令,即乘法操作的結果為令,即乘法操作的結果為64位。兩類指令共有以下位。兩類指令共有以下6條。條。MUL:32位乘法指令。MLA:32位帶加數的乘法指令。SMULL:64位有符號數乘法指令。
16、SMLAL:64位帶加數的有符號數乘法指令。UMULL:64位無符號數乘法指令。UMLAL:64位帶加數的無符號數乘法指令。253.1.4 雜類的算術指令雜類的算術指令在在ARMv5及以上的版本中,包含一條特別的指令及以上的版本中,包含一條特別的指令CLZ,用,用于計算操作數最高端于計算操作數最高端0的個數。這條指令主要用于以下兩種的個數。這條指令主要用于以下兩種場合:場合:計算操作數規(guī)范化(使其最高位為1)時需要左移的位數。確定一個優(yōu)先級掩碼中的最高優(yōu)先級(最高位的優(yōu)先級)。CLZ 前導前導0個數計數指令個數計數指令CLZ指令用于計算寄存器中操作數最高端指令用于計算寄存器中操作數最高端0的個
17、數。如果操的個數。如果操作數的作數的bit31為為1,則指令返回,則指令返回0;如果操作數為;如果操作數為0,則指令,則指令返回返回32。指令的編碼格式指令的編碼格式263.1.5 狀態(tài)寄存器訪問指令狀態(tài)寄存器訪問指令ARM中有兩條指令用于在狀態(tài)寄存器和通用寄存器中有兩條指令用于在狀態(tài)寄存器和通用寄存器之間傳送數據。之間傳送數據。關于狀態(tài)寄存器,這里僅強調以下幾點。關于狀態(tài)寄存器,這里僅強調以下幾點。(1)狀態(tài)寄存器中,有些位是當前沒有使用的,但在ARM將來的版本中有可能使用這些位,因此用戶程序不要使用這些位。(2)程序不能通過直接修改CPSR中的T控制位直接將程序狀態(tài)切換到Thumb狀態(tài),必
18、須通過BX等指令完成程序狀態(tài)的切換。(3)通常修改狀態(tài)寄存器是通過“讀取-修改-寫回”的操作序列來實現的。(4)狀態(tài)寄存器訪問指令包括以下兩條。MRS:狀態(tài)寄存器到通用寄存器的傳送指令。MSR:通用寄存器到狀態(tài)寄存器的傳送指令。273.1.6 Load/Store 內存訪問指令內存訪問指令Load指令用于從內存中讀取數據放入寄存器中;指令用于從內存中讀取數據放入寄存器中;Store指令用于將寄存器中的數據保存到內存。指令用于將寄存器中的數據保存到內存。ARM有兩大類的有兩大類的Load/Store指令:一類用于操作指令:一類用于操作32位的字類型數據以及位的字類型數據以及8位無符號的字節(jié)類型數
19、位無符號的字節(jié)類型數據;另一類用于操作據;另一類用于操作16位半字類型的數據以及位半字類型的數據以及8位位的有符號字節(jié)類型的數據。的有符號字節(jié)類型的數據。Load/Store 內存訪問指令的一個操作數放在寄存內存訪問指令的一個操作數放在寄存器中,另一個操作數的尋址方式參見器中,另一個操作數的尋址方式參見2.2節(jié)。節(jié)。283.1.6 Load/Store 內存訪問指令內存訪問指令用于操作用于操作32位的字類型數據以及位的字類型數據以及8位無符號的字節(jié)類型數據位無符號的字節(jié)類型數據的的Load/Store指令有以下指令。指令有以下指令。LDR:字數據讀取指令。LDRB:字節(jié)數據讀取指令。LDRBT
20、:用戶模式的字節(jié)數據讀取指令。LDRH:半字數據讀取指令。LDRSB:有符號的字節(jié)數據讀取指令。LDRSH:有符號的半字數據讀取指令。LDRT:用戶模式的字數據讀取指令。STR:字數據寫入指令。STRB:字節(jié)數據寫入指令。STRBT:用戶模式字節(jié)數據寫入指令。STRH:半字數據寫入指令。STRT:用戶模式字數據寫入指令。293.1.7 批量批量 Load/Store 內存訪問指令內存訪問指令批量批量 Load 內存訪問指令可以一次從連續(xù)的內存單內存訪問指令可以一次從連續(xù)的內存單元中讀取數據,傳送到指令中的內存列表中的各個元中讀取數據,傳送到指令中的內存列表中的各個寄存器中。寄存器中。批量批量S
21、tore內存訪問指令可以將指令中寄存器列表內存訪問指令可以將指令中寄存器列表中的各個寄存器值寫入到內存中,內存的地址由指中的各個寄存器值寫入到內存中,內存的地址由指令中的尋址模式確定。令中的尋址模式確定。批量批量Load/Store內存訪問指令的語法格式如下:內存訪問指令的語法格式如下: LDM|STM Rn!, 其中,操作數的尋址方式參見其中,操作數的尋址方式參見2.2節(jié)。節(jié)。303.1.7 批量批量 Load/Store 內存訪問指令內存訪問指令批量批量 Load/Store 內存訪問指令主要有以下幾條。內存訪問指令主要有以下幾條。LDM(1):批量內存字數據讀取指令。LDM(2):用戶模
22、式的批量內存字數據讀取指令。LDM(3):帶狀態(tài)寄存器的批量內存字數據讀取指令。STM(1):批量內存字數據寫入指令。STM(2):用戶模式的批量內存字數據寫入指令。313.1.8 信號量操作指令信號量操作指令信號量用于進程間的同步和互斥。對信號量的操作信號量用于進程間的同步和互斥。對信號量的操作通常要求是一個原子操作,即在一條指令中完成信通常要求是一個原子操作,即在一條指令中完成信號量的讀取和修改操作。號量的讀取和修改操作。ARM提供了如下兩條指令提供了如下兩條指令來完成信號量的操作。來完成信號量的操作。SWP:交換指令。SWPB:字節(jié)交換指令。323.1.9 異常中斷產生指令異常中斷產生指
23、令ARM有兩條異常中斷產生指令。有兩條異常中斷產生指令。SWI:軟中斷指令。SWI用于產生SWI異常中斷,ARM正是通過這種機制實現在用戶模式中對操作系統(tǒng)中特權模式的程序的調用。BKPT:斷點中斷指令。BKPT在ARMv5及以上的版本中引入,主要用于產生軟件斷點,供調試程序使用。333.1.10 ARM協處理器指令協處理器指令ARM支持支持16個協處理器。個協處理器。ARM協處理器可以部分地執(zhí)行一條指令,然后產生異常中協處理器可以部分地執(zhí)行一條指令,然后產生異常中斷,如像除法運算除數為斷,如像除法運算除數為0的情況。所有這些操作均由的情況。所有這些操作均由ARM協處理器決定,協處理器決定,AR
24、M處理器并不參與這些操作。同樣,處理器并不參與這些操作。同樣,ARM協處理器指令中的協處理器的寄存器標識符以及操作協處理器指令中的協處理器的寄存器標識符以及操作類型助記符也有各種不同的實現定義,程序員可以通過宏來類型助記符也有各種不同的實現定義,程序員可以通過宏來定義這些指令的語法格式。定義這些指令的語法格式。ARM協處理器指令包括以下協處理器指令包括以下3類:類:用于ARM處理器初始化ARM協處理器的數據處理操作。用于ARM處理器的寄存器和ARM協處理器的寄存器間的數據傳送操作。用于在ARM協處理器的寄存器和內存單元之間傳送數據。343.1.10 ARM協處理器指令協處理器指令這些指令包括以
25、下這些指令包括以下5條。條。CDP:協處理器數據操作指令。LDC:協處理器數據讀取指令。STC:協處理器數據寫入指令。MCR:ARM寄存器到協處理器寄存器的數據傳送指令。MRC:協處理器寄存器到ARM寄存器的數據傳送指令。353.2 一些基本的一些基本的ARM指令功能段指令功能段本節(jié)介紹一些基本的本節(jié)介紹一些基本的ARM指令代碼段。通過對這些指令代碼段。通過對這些代碼段的分析,進一步理解相關的代碼段的分析,進一步理解相關的ARM指令的用指令的用法,逐步學習如何使用法,逐步學習如何使用ARM指令編寫高效率的程指令編寫高效率的程序。本節(jié)主要包括以下幾部分的內容:序。本節(jié)主要包括以下幾部分的內容:算
26、術邏輯運算指令的應用。跳轉指令的應用。Load/Store指令的應用。批量Load/Store指令的應用。信號量指令的應用。與系統(tǒng)相關的一些指令的應用。363.2.1 算術邏輯運算指令的應用算術邏輯運算指令的應用1. 位操作指令應用舉例位操作指令應用舉例2. 實現乘法的指令段舉例實現乘法的指令段舉例3. 64位數據運算舉例位數據運算舉例4. 轉換內存中數據存儲方式的指令段轉換內存中數據存儲方式的指令段一種是字數據中的高位數據存放在高地址處,低位數據存放在低地址處另一種是字中高位數據存放在低地址處,低位數據存放在高地址處373.2.2 跳轉指令的應用跳轉指令的應用1. 子程序調用子程序調用2.
27、條件執(zhí)行條件執(zhí)行3. 條件判斷語句條件判斷語句4. 循環(huán)語句循環(huán)語句5. 多路分支程序語句多路分支程序語句383.2.3 Load/Store指令的應用指令的應用1. 鏈表操作鏈表操作2. 簡單的串比較簡單的串比較3. 長跳轉長跳轉4. 多路跳轉多路跳轉393.2.4 批量批量Load/Store指令的應用指令的應用1. 簡單的塊復制簡單的塊復制2. 子程序進入和退出時數據的保存和恢復子程序進入和退出時數據的保存和恢復403.2.5 信號量指令的應用信號量指令的應用信號量用于實現對臨界區(qū)數據訪問的同步。下面的信號量用于實現對臨界區(qū)數據訪問的同步。下面的代碼說明了在代碼說明了在ARM中如何實現這
28、一過程。代碼中用中如何實現這一過程。代碼中用進程標識符來表示各信號量的所有者,代碼執(zhí)行前進程標識符來表示各信號量的所有者,代碼執(zhí)行前進程的標識符保存在進程的標識符保存在R1中,信號量的地址保存在中,信號量的地址保存在R0中。當信號量值為中。當信號量值為0時,表示與該信號量相關的時,表示與該信號量相關的臨界區(qū)可用;當信號量值為臨界區(qū)可用;當信號量值為1時,表示當前有進程時,表示當前有進程正在查看該信號量的值。如果當前進程查看的信號正在查看該信號量的值。如果當前進程查看的信號量正忙,當前進程將一直等待該信號量。為了避免量正忙,當前進程將一直等待該信號量。為了避免當前進程的查詢操作阻塞操作系統(tǒng)的進程
29、調度,可當前進程的查詢操作阻塞操作系統(tǒng)的進程調度,可以在下一次查詢之前完成操作系統(tǒng)中的系統(tǒng)調用,以在下一次查詢之前完成操作系統(tǒng)中的系統(tǒng)調用,使當前進程休眠一段時間。使當前進程休眠一段時間。參見教材P116413.2.6 與系統(tǒng)相關的一些指令代碼段與系統(tǒng)相關的一些指令代碼段1. SWI中斷處理程序示例中斷處理程序示例2. IRQ中斷處理程序示例中斷處理程序示例3. 進程切換進程切換423.3 Thumb指令介紹指令介紹在在ARM體系結構中,體系結構中,ARM指令集中的指令是指令集中的指令是32位指令,其位指令,其執(zhí)行效率很高。對于存儲系統(tǒng)數據總線為執(zhí)行效率很高。對于存儲系統(tǒng)數據總線為16位的應用
30、系位的應用系統(tǒng),統(tǒng),ARM體系提供了體系提供了Thumb指令集。指令集。Thumb指令集是對指令集是對ARM指令集的一個子集進行重新編碼而得到的,其指令長指令集的一個子集進行重新編碼而得到的,其指令長度為度為16位。在位。在ARM體系的體系的T變種變種(T Variant)的版本中,同時的版本中,同時支持支持ARM指令集和指令集和Thumb指令集,而且遵守一定的調用規(guī)指令集,而且遵守一定的調用規(guī)則時,則時,Thumb子程序和子程序和ARM子程序可以相互調用。子程序可以相互調用。通常在處理器執(zhí)行通常在處理器執(zhí)行ARM程序時,稱處理器處于程序時,稱處理器處于ARM狀態(tài);狀態(tài);在處理器執(zhí)行在處理器執(zhí)
31、行Thumb程序時,稱處理器處于程序時,稱處理器處于Thumb狀態(tài)。狀態(tài)。注意處理器狀態(tài)和處理器模式指的是不同的概念。注意處理器狀態(tài)和處理器模式指的是不同的概念。Thumb指令集并沒有改變指令集并沒有改變ARM體系底層的程序設計模型,體系底層的程序設計模型,只是在該模型上增加了一些限制條件。只是在該模型上增加了一些限制條件。Thumb指令集中的指令集中的數據處理指令的操作數仍然是數據處理指令的操作數仍然是32位的,指令尋址地址也是位的,指令尋址地址也是32位的。位的。433.3 Thumb指令介紹指令介紹處理器執(zhí)行處理器執(zhí)行Thumb指令時,可以使用的整數寄存指令時,可以使用的整數寄存器通常為
32、器通常為R0R7,有些指令還使用到了程序計數,有些指令還使用到了程序計數器寄存器器寄存器PC(R15)、程序返回寄存器、程序返回寄存器LR(R14)以及以及棧指針寄存器棧指針寄存器SP(R13)。在。在Thumb狀態(tài)下,讀取狀態(tài)下,讀取R15寄存器時,位寄存器時,位0值為值為0,位,位31:1包含了程序計包含了程序計數器的值;在向數器的值;在向R15寄存器寫入數據時時,位寄存器寫入數據時時,位0被被忽略,位忽略,位31:1被設置成當前程序計數器的值。被設置成當前程序計數器的值。Thumb指令集沒有提供訪問指令集沒有提供訪問CPSR/SPSR寄存器的寄存器的指令。處理器根據指令。處理器根據CPS
33、R寄存器中的寄存器中的T位來確定指位來確定指令類型:令類型:當T位為0時,指令為ARM指令。當T位為1時,指令為Thumb指令。44第第4章章 ARM匯編語言程序設計匯編語言程序設計本章介紹如何編寫本章介紹如何編寫ARM和和Thumb匯編語言程序,匯編語言程序,同時介紹同時介紹ARM匯編編譯器匯編編譯器armasm的使用方法。的使用方法。464.1 偽偽 操操 作作偽操作不像機器指令那樣在計算機運行期間由機器執(zhí)行,它偽操作不像機器指令那樣在計算機運行期間由機器執(zhí)行,它是在匯編程序對源程序匯編期間由匯編程序處理的。宏是一是在匯編程序對源程序匯編期間由匯編程序處理的。宏是一段獨立的程序代碼。在程序
34、中通過宏指令調用該宏。當程序段獨立的程序代碼。在程序中通過宏指令調用該宏。當程序被匯編時,匯編程序將對每個宏調用進行展開,用宏定義體被匯編時,匯編程序將對每個宏調用進行展開,用宏定義體取代源程序中的宏指令。本節(jié)介紹以下類型的取代源程序中的宏指令。本節(jié)介紹以下類型的ARM偽操作偽操作和宏指令:和宏指令:符號定義(Symbol Definition)偽操作。數據定義(Data Definition)偽操作。匯編控制(Assembly Control)偽操作。數據幀描述(Frame Description)偽操作。信息報告(Reporting)偽操作。其他(Miscellaneous)偽操作。474
35、.1.1 符號定義偽操作符號定義偽操作符號定義符號定義(Symbol Definition)偽操作用于定義偽操作用于定義ARM匯編程序中的變量,對變量進行賦值以及定義匯編程序中的變量,對變量進行賦值以及定義寄存器名稱。包括以下偽操作。寄存器名稱。包括以下偽操作。GBLA、GBLL及GBLS:聲明全局變量。LCLA、LCLL及LCLS:聲明局部變量。SETA、SETL及SETS:給變量賦值。RLIST:為通用寄存器列表定義名稱。CN:為協處理器的寄存器定義名稱。CP:為協處理器定義名稱。DN及SN:為VFP的寄存器定義名稱。FN:為FPA的浮點寄存器定義名稱。484.1.2 數據定義偽操作數據定
36、義偽操作數據定義數據定義(Data Definition)偽操作包括以下具體的偽操作包括以下具體的偽操作。偽操作。LTORG:聲明一個數據緩沖池(Literal Pool)的開始。MAP:定義一個結構化的內存表(Storage Map)的首地址。FIELD:定義結構化的內存表中的一個數據域(Field)。SPACE:分配一塊內存單元,并用0初始化。DCB:分配一段字節(jié)的內存單元,并用指定的數據初始化。DCD及DCDU:分配一段字的內存單元,并用指定的數據初始化。DCDO:分配一段字的內存單元,并將各單元的內容初始化成該單元相對于靜態(tài)基值寄存器的偏移量。494.1.2 數據定義偽操作數據定義偽操
37、作DCFD及DCFDU:分配一段雙字的內存單元,并用雙精度的浮點數據初始化。DCFS及DCFSU:分配一段字的內存單元,并用單精度的浮點數據初始化。DCI:分配一段字節(jié)的內存單元,用指定的數據初始化,指定內存單元中存放的是代碼,而不是數據。DCQ及DCQU:分配一段雙字的內存單元,并用64位的整數數據初始化。DCW及DCWU:分配一段半字的內存單元,并用指定的數據初始化。DATA:在代碼段中使用數據?,F已不再使用,僅用于保持向前兼容。504.1.3 匯編控制偽操作匯編控制偽操作匯編控制匯編控制(Assembly Control)偽操作包括下面?zhèn)尾僮靼ㄏ旅娴膫尾僮鳎旱膫尾僮鳎篒F、ELSE及E
38、NDIFWHILE及WENDMACRO及MENDMEXIT514.1.4 數據幀描述偽操作數據幀描述偽操作棧中數據幀描述偽操作主要用于調試,這里不棧中數據幀描述偽操作主要用于調試,這里不介紹這部分內容。感興趣的讀者可以參考介紹這部分內容。感興趣的讀者可以參考ARM的相關資料。的相關資料。524.1.5 信息報告?zhèn)尾僮餍畔蟾鎮(zhèn)尾僮餍畔蟾嫘畔蟾?Reporting)偽操作包括下列具體的偽操作包括下列具體的偽操作:偽操作:ASSERTINFOOPTTTL及SUBT534.1.6 其他的偽操作其他的偽操作這些雜類的偽操作包括:這些雜類的偽操作包括:CODE16及CODE32EQUAREAENTR
39、YENDALIGNEXPORT或GLOBALIMPORTEXTERNGET或INCLUDE544.1.6 其他的偽操作其他的偽操作INCBINKEEPNOFPREQUIREREQUIRE8及PRESERVE8RNROUT554.2 ARM匯編語言偽指令匯編語言偽指令ARM中偽指令不是真正的中偽指令不是真正的ARM指令或者指令或者Thumb指指令,這些偽指令在匯編編譯器對源程序進行匯編處令,這些偽指令在匯編編譯器對源程序進行匯編處理時被替換成對應的理時被替換成對應的ARM或者或者Thumb指令指令(序列序列)。ARM偽指令包括偽指令包括ADR、ADRL、LDR和和NOP。1. ADR (小范圍的
40、地址讀取偽指令)2. ADRL(中等范圍的地址讀取偽指令)3. LDR大范圍的地址讀取偽指令4. NOP 空操作偽指令564.3 ARM匯編語言語句的格式匯編語言語句的格式ARM匯編語言語句格式如下:匯編語言語句格式如下:symbol instruction|directive|pseudo-instruction ; comment其中的符號及參數說明如下:其中的符號及參數說明如下:instruction為指令。在ARM匯編語言中,指令不能從一行的行頭開始。在一行語句中,指令的前面必須有空格或者符號。directive為偽操作。pseudo-instruction為偽指令。symbol為符號
41、。在ARM匯編語言中,符號必須從一行的行頭開始,并且符號中不能包含空格。在指令和偽指令中,符號用作地址標號(label);在有些偽操作中,符號用作變量或者常量。comment為語句的注釋。在ARM匯編語言中,注釋以分號(;)開頭。注釋的結尾即為一行的結尾。注釋也可以單獨占用一行。574.3.1 ARM匯編語言中的符號匯編語言中的符號在在ARM匯編語言中,符號匯編語言中,符號(Symbols)可以代表地址可以代表地址(Addresses)、變量、變量(Variables)和數字常量和數字常量(Numeric Constants)。當符號代表地址時,又。當符號代表地址時,又稱為標號稱為標號(Lab
42、el)。當標號以數字開頭時,其作用范圍為當前段。當標號以數字開頭時,其作用范圍為當前段(沒有使沒有使用用ROUT偽操作時偽操作時),這種標號又稱為局部標號,這種標號又稱為局部標號(Local Label)。符號包。符號包括變量、數字常量、標號和局部標號。括變量、數字常量、標號和局部標號。符號的命名規(guī)則如下:符號的命名規(guī)則如下:符號由大小寫字母、數字以及下劃線組成。局部標號以數字開頭,其他的符號都不能以數字開頭。符號是區(qū)分大小寫的。符號中的所有字符都是有意義的。符號在其作用范圍內必須惟一,即在其作用范圍內不可有同名的符號。程序中的符號不能與系統(tǒng)內部變量或者系統(tǒng)預定義的符號同名。程序中的符號通常不
43、要與指令助記符或者偽操作同名。當程序中的符號與指令助記符或者偽操作同名時,可用雙豎線將符號括起來,如|require|,這時雙豎線并不是符號的組成部分。584.3.1 ARM匯編語言中的符號匯編語言中的符號1. 變量變量2. 數字常量數字常量3. 匯編時的變量替換匯編時的變量替換4. 標號標號5. 局部標號局部標號594.3.2 ARM匯編語言中的表達式匯編語言中的表達式表達式是由符號、數值、單目或多目操作符以及括表達式是由符號、數值、單目或多目操作符以及括號組成的。在一個表達式中,各種元素的優(yōu)先級如號組成的。在一個表達式中,各種元素的優(yōu)先級如下所示:下所示:括號內的表達式優(yōu)先級最高。各種操作
44、符有一定的優(yōu)先級。相鄰的單目操作符的執(zhí)行順序為由右到左,單目操作符優(yōu)先級高于其他操作符。優(yōu)先級相同的雙目操作符執(zhí)行順序為由左到右。604.3.2 ARM匯編語言中的表達式匯編語言中的表達式1. 字符串表達式字符串表達式(1)字符串(2)字符串變量(3)操作符LEN CHRSTRLEFTRIGHTCC(4)字符變量的聲明和賦值(5)字符串表達式應用舉例614.3.2 ARM匯編語言中的表達式匯編語言中的表達式2. 數字表達式數字表達式(1)整數數字量(2)浮點數字量(3)數字變量(4)操作符NOT 按位取反+、/及 MOD 算術操作符ROL、ROR、SHL及SHR移位(循環(huán)移位操作)AND、OR
45、及EOR按位邏輯操作符624.3.2 ARM匯編語言中的表達式匯編語言中的表達式3. 基于寄存器和基于基于寄存器和基于PC的表達式的表達式(1)BASE(2)INDEX(3)+、4. 邏輯表達式邏輯表達式(1)關系操作符(2)邏輯操作符5. 其他的一些操作符其他的一些操作符(1)?(2)DEF(3)SB_OFFSET_19_12 (4)SB_OFFSET_11_0634.4 ARM匯編語言程序的格式匯編語言程序的格式本小節(jié)介紹本小節(jié)介紹ARM匯編語言程序的基本格式以及匯編語言程序的基本格式以及子程序間調用的格式。子程序間調用的格式。644.4.1 匯編語言程序的格式匯編語言程序的格式ARM匯編
46、語言以段匯編語言以段(Section)為單位組織源文件。段是相對為單位組織源文件。段是相對獨立的、具有特定名稱的、不可分割的指令或者數據序列。獨立的、具有特定名稱的、不可分割的指令或者數據序列。段又可以分為代碼段和數據段,代碼段存放執(zhí)行代碼,數據段又可以分為代碼段和數據段,代碼段存放執(zhí)行代碼,數據段存放代碼運行時需要用到的數據。一個段存放代碼運行時需要用到的數據。一個ARM源程序至少源程序至少需要一個代碼段,大的程序可以包含多個代碼段和數據段。需要一個代碼段,大的程序可以包含多個代碼段和數據段。ARM匯編語言源程序經過匯編處理后,生成一個可執(zhí)行的匯編語言源程序經過匯編處理后,生成一個可執(zhí)行的映
47、像文件映像文件(類似于類似于Windows系統(tǒng)下的系統(tǒng)下的EXE文件文件)。該可執(zhí)行的。該可執(zhí)行的映像文件通常包括下面映像文件通常包括下面3部分:部分:一個或多個代碼段。代碼段通常是只讀的。零個或多個包含初始值的數據段。這些數據段通常是可讀寫的。零個或多個不包含初始值的數據段。這些數據段被初始化為0,它們通常是可讀寫的。654.4.2 匯編語言子程序的調用匯編語言子程序的調用在在ARM匯編語言中,子程序調用是通過匯編語言中,子程序調用是通過BL指令完指令完成的。成的。BL指令的語法格式如下:指令的語法格式如下:BL subname其中,其中,subname是調用的子程序的名稱。是調用的子程序的
48、名稱。BL指令完成兩個操作:將子程序的返回地址放在指令完成兩個操作:將子程序的返回地址放在LR寄存器中,同時將寄存器中,同時將PC寄存器值設置成目標子程寄存器值設置成目標子程序的第一條指令地址。序的第一條指令地址。在子程序返回時,可以通過將在子程序返回時,可以通過將LR寄存器的值傳送寄存器的值傳送到到PC寄存器中來實現。寄存器中來實現。子程序調用時,通常使用寄存器子程序調用時,通常使用寄存器R0R3來傳遞參來傳遞參數和返回結果,這些在后面的編程模型中還會有詳數和返回結果,這些在后面的編程模型中還會有詳細的介紹。細的介紹。664.5 ARM匯編編譯器的使用匯編編譯器的使用內嵌的內嵌的ARM匯編編
49、譯器是匯編編譯器是ARM中中C/C+編譯器的一部分,編譯器的一部分,它沒有自己的命令行格式。在它沒有自己的命令行格式。在ARMASM命令中,除了文件命令中,除了文件名區(qū)分大小寫之外,其他的參數都不區(qū)分大小寫。名區(qū)分大小寫之外,其他的參數都不區(qū)分大小寫。ARMASM的語法格式如下所示:的語法格式如下所示:armasm -16|-32 -apcs none|/qualifier/qualifier.-bigend|-littleend -checkreglist -cpu cpu -depend dependfile|-m|-md-errors errorfile -fpu name -g -he
50、lp -i dir ,dir -keep -listlistingfile options -maxcache n -memaccess attributes -nocache-noesc -noregs -nowarn -o filename -predefine directive -split_ldm-unsafe -via file inputfile674.6 匯編程序設計舉例匯編程序設計舉例在本節(jié)中,將通過一些例子來說明在本節(jié)中,將通過一些例子來說明ARM中偽操中偽操作以及指令的用法。作以及指令的用法。4.6.1小節(jié)中給出了一些偽小節(jié)中給出了一些偽操作的實例,操作的實例,4.6.2
51、小節(jié)中是一些小節(jié)中是一些ARM匯編程序匯編程序的實例。的實例。684.6.1 ARM中偽操作的使用實例中偽操作的使用實例程序程序4.1 ARM中偽操作的使用實例:中偽操作的使用實例:參見教材P166694.6.2 ARM匯編程序的實例匯編程序的實例1. 數據塊復制數據塊復制2. ADR偽操作的使用實例偽操作的使用實例3. 利用跳轉表實現程序跳轉利用跳轉表實現程序跳轉4. 偽指令偽指令LDR的使用實例的使用實例70第第5章章 ARM的存儲系統(tǒng)的存儲系統(tǒng)與其他的中、低檔單片機不同,與其他的中、低檔單片機不同,ARM處理器中處理器中可以包含一個存儲管理部件。本章介紹可以包含一個存儲管理部件。本章介紹
52、ARM體體系中兩種典型的存儲管理實現機制。并在最后系中兩種典型的存儲管理實現機制。并在最后給出一個實例。給出一個實例。725.1 ARM存儲系統(tǒng)概述存儲系統(tǒng)概述ARM存儲系統(tǒng)的體系結構可以適應多種不同的嵌入式應用存儲系統(tǒng)的體系結構可以適應多種不同的嵌入式應用系統(tǒng)。最簡單的存儲系統(tǒng)使用普通的地址映射機制,就像在系統(tǒng)。最簡單的存儲系統(tǒng)使用普通的地址映射機制,就像在一些簡單的單片機系統(tǒng)中一樣,地址空間的分配方式是固定一些簡單的單片機系統(tǒng)中一樣,地址空間的分配方式是固定的,系統(tǒng)中各部分都使用物理地址。而一些復雜的系統(tǒng)可能的,系統(tǒng)中各部分都使用物理地址。而一些復雜的系統(tǒng)可能包括一種或者多種下面的技術,從
53、而可以提供功能更為強大包括一種或者多種下面的技術,從而可以提供功能更為強大的存儲系統(tǒng):的存儲系統(tǒng):系統(tǒng)中可能包含多種類型的存儲器件通過使用Cache及Write Buffer技術,可以縮小處理器和存儲系統(tǒng)的速度差別,從而提高系統(tǒng)的整體性能。內存管理部件使用內存映射技術實現虛擬空間到物理空間的映射引入存儲保護機制,增強系統(tǒng)的安全性。引入一些機制,保證將I/O操作映射成內存操作后,各種I/O操作能夠得到正確的結果。735.1 ARM存儲系統(tǒng)概述存儲系統(tǒng)概述本章中主要介紹以下內容。在介紹相關內容時,將本章中主要介紹以下內容。在介紹相關內容時,將以以LinkUp公司的通用公司的通用ARM芯片芯片L72
54、05作為例子。作為例子。ARM中用于存儲管理的系統(tǒng)控制協處理器CP15。ARM中的存儲管理部件MMU(Memory Management Unit)。ARM中的Cache及Write Buffer技術。快速進程上下文切換技術。745.2 ARM中用于存儲管理的系統(tǒng)控制協處理器中用于存儲管理的系統(tǒng)控制協處理器CP15CP15可以包含可以包含16個個32位的寄存器,其編號為位的寄存器,其編號為015。實際。實際上,對于某些編號的寄存器,可能對應有多個物理寄存器,上,對于某些編號的寄存器,可能對應有多個物理寄存器,在指令中可指定特定的標志位來區(qū)分這些物理寄存器。這種在指令中可指定特定的標志位來區(qū)分這
55、些物理寄存器。這種機制有些類似于機制有些類似于ARM中的寄存器,當處于不同的處理器模中的寄存器,當處于不同的處理器模式時,某些式時,某些ARM寄存器可能是不同的物理寄存器,比如對寄存器可能是不同的物理寄存器,比如對于寄存器于寄存器SPSR,每一種處理器模式下都對應一個獨立的物,每一種處理器模式下都對應一個獨立的物理寄存器理寄存器(用戶模式和系統(tǒng)模式對應同樣的物理寄存器,這用戶模式和系統(tǒng)模式對應同樣的物理寄存器,這是一個例外是一個例外)。CP15中的寄存器可能是只讀的,也可能是只寫的,還有一中的寄存器可能是只讀的,也可能是只寫的,還有一些是可以讀寫的。對于每一種寄存器,將會詳細介紹:些是可以讀寫
56、的。對于每一種寄存器,將會詳細介紹:寄存器的訪問類型(只讀/只寫/讀寫)。各種訪問操作對于寄存器的作用。寄存器是否對應有多個物理寄存器。寄存器的具體作用。755.2.1 訪問訪問CP15寄存器的指令寄存器的指令訪問訪問CP15寄存器的指令有下面兩種。寄存器的指令有下面兩種。MCR:ARM寄存器到協處理器寄存器的數據傳送指令。MRC:協處理器寄存器到ARM寄存器的數據傳送指令。MCR指令和指令和MRC指令只能在處理器模式是系統(tǒng)模指令只能在處理器模式是系統(tǒng)模式時執(zhí)行,在用戶模式下執(zhí)行式時執(zhí)行,在用戶模式下執(zhí)行MCR指令和指令和MRC指指令將會觸發(fā)未定義指令的異常中斷。令將會觸發(fā)未定義指令的異常中斷
57、。765.2.2 CP15中的寄存器中的寄存器1. CP15中的寄存器中的寄存器C0(1)標識符寄存器ARM7之后的處理器ARM7處理器ARM7之前的處理器(2)Cache類型標識符寄存器2. CP15中的寄存器中的寄存器C1CP15中的寄存器C1是一個控制寄存器,它包括以下控制功能:禁止/使能MMU以及其他的與存儲系統(tǒng)相關的功能。配置存儲系統(tǒng)以及ARM處理器中的相關部分的工作方式。775.3 存儲器管理單元存儲器管理單元MMU5.3.1 存儲器管理單元存儲器管理單元MMU概述概述在ARM系統(tǒng)中,存儲器管理單元MMU主要完成以下工作:虛擬存儲空間到物理存儲空間的映射。在ARM中采用了頁式虛擬存
58、儲管理。它把虛擬地址空間分成一個個固定大小的塊,每一塊稱為一頁,把物理內存的地址空間也分成同樣大小的頁。頁的大小可以分為粗粒度和細粒度兩種。MMU就要實現從虛擬地址到物理地址的轉換。存儲器訪問權限的控制。設置虛擬存儲空間的緩沖的特性。785.3.1 存儲器管理單元MMU概述頁表頁表(Translate Table)是實現上述這些功能的重要是實現上述這些功能的重要手段,它是一個位于內存中的表。手段,它是一個位于內存中的表。頁表存放在內存中,系統(tǒng)通常用一個寄存器來保存頁表存放在內存中,系統(tǒng)通常用一個寄存器來保存頁表的基地址。在頁表的基地址。在ARM中,系統(tǒng)控制協處理器中,系統(tǒng)控制協處理器CP15的
59、寄存器的寄存器C2用來保存頁表的基地址。用來保存頁表的基地址。當當CPU需要訪問內存時,先在需要訪問內存時,先在TLB中查找需要的地中查找需要的地址變換條目。如果該條目不存在,址變換條目。如果該條目不存在,CPU從位于內存從位于內存中的頁表中查詢,并把相應的結果添加到中的頁表中查詢,并把相應的結果添加到TLB中。中。這樣,當這樣,當CPU下一次又需要該地址變換條目時,就下一次又需要該地址變換條目時,就可以從可以從TLB中直接得到了,從而使地址變換的速度中直接得到了,從而使地址變換的速度大大加快。大大加快。795.3.1 存儲器管理單元MMU概述當內存中的頁表內容改變,或者通過修改系統(tǒng)控制協處理
60、器當內存中的頁表內容改變,或者通過修改系統(tǒng)控制協處理器CP15的寄的寄存器存器C2使用新的頁表時,使用新的頁表時,TLB中的內容需要全部清除。中的內容需要全部清除。MMU提供了相提供了相關的硬件支持這種操作。系統(tǒng)控制協處理器關的硬件支持這種操作。系統(tǒng)控制協處理器CP15的寄存器的寄存器C8用來控制用來控制清除清除TLB內容的相關操作。內容的相關操作。MMU可以將某些地址變換條目鎖定可以將某些地址變換條目鎖定(Locked Down)在在TLB中,從而使中,從而使得進行與該地址變換條目相關的地址變換速度保持很快。在得進行與該地址變換條目相關的地址變換速度保持很快。在MMU中,中,寄存器寄存器C1
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025合同違約賠償協議書10篇
- 公司股份轉讓協議書七篇
- 公司盤活閑置資產和清收清欠工作專題會講話
- 單位租車協議書標準范本7篇
- 自發(fā)性細菌性腹膜炎病因介紹
- (立項備案申請模板)低溫預浸纖維項目可行性研究報告參考范文
- 1.1《沁園春·長沙》【中職專用】高一語文(高教版2023基礎模塊上冊)
- (2024)旅游集散中心建設項目申請報告可行性研究報告(一)
- 房屋構造識圖與建模- 趙靖 任務三 基礎類型與 構61課件講解
- 2023年浸漬、涂布或包覆處理紡織物項目融資計劃書
- 語文修改語病-三年(2022-2024)高考病句試題真題分析及 備考建議(課件)
- 國家開放大學電大《計算機應用基礎(本)》終結性考試試題答案(格式已排好)任務一
- 中華護理學會會員申請表(普通+資深會員)
- 電子政務教案人民大學
- 最新國家電網公司電力安全工作規(guī)程
- (完整版)HSE管理體系及措施
- 淺談吉林省中藥材產業(yè)發(fā)展
- 職業(yè)生涯規(guī)劃檔案建立過程
- 圖形找規(guī)律專項練習60題(有答案)
- 小型步進電機控制系統(tǒng)設計
- 普通發(fā)票銷售清單
評論
0/150
提交評論