ARM彙編中^、!、cxsf符號和movs等指令使用

ARM彙編中^!cxsf符號和movs等指令使用

轉自:http://hi.baidu.com/chenwenjun721/item/ad25c713c5b5598b89a95661

淺析arm彙編中^!cxsf符號和movs等指令使用學習-1

文章來源:http://gliethttp.cublog.cn

.macro restore_user_regs
   ldr r1,[sp, #S_PSR]
   ldr lr,[sp, #S_PC]!   @ !
用來控制基址變址尋址的最終新地址是否進行回寫操作,
                       @
執行ldr之後sp被回寫成sp+#S_PC基址變址尋址的新地址
   msrspsr,r1           @
cpsr的值保存到spsr
   ldmdb sp,{r0 - lr}^   @lr=[sp-1*4],r13=[sp-2*4],r12=[sp-3*4],......,r0=[sp-15*4]
                       @
因爲沒對pc賦值,所以^的表示將數據恢復到User模式的[r0-lr]寄存器組中[gliethttp]
   mov r0,r0
 
   add sp,sp,#S_FRAME_SIZE - S_PC
   movs pc,lr
.endm

其他指令正在學習中[隨時補充gliethttp]
-----------------------------
1.ldr ip,[sp],#4
sp中內容存入ip,之後sp=sp+4;
   ldr ip,[sp,#4]
sp+4這個新地址下內容存入ip,之後sp值保持不變
   ldr ip,[sp,#4]!
sp+4這個新地址下內容存入ip,之後sp=sp+4將新地址值賦給sp
   str ip,[sp],#4
ip存入sp地址處,之後sp=sp+4;
   str ip,[sp,#4]
ip存入sp+4這個新地址,之後sp值保持不變
   str ip,[sp,#4]!
ip存入sp+4這個新地址,之後sp=sp+4將新地址值賦給sp
-----------------------------
2.movs r1,#3 ;movs
將導致ALU被更改,因爲r1賦值非0,即操作結果r00,所以ALUZ標誌清0
   bne 1f    ;
因爲Z=0,說明不等,所以向前跳到標號1:所在處繼續執行其他語句
-----------------------------
3.LDM
表示裝載,STM表示存儲.
   LDMED LDMIB
預先增加裝載
   LDMFD LDMIA
過後增加裝載
   LDMEA LDMDB
預先減少裝載
   LDMFA LDMDA
過後減少裝載

   STMFA STMIB 預先增加存儲
   STMEA STMIA
過後增加存儲
   STMFD STMDB
預先減少存儲
   STMED STMDA
過後減少存儲

注意ED不同於IB;只對於預先減少裝是相同的.在存儲的時候,ED是過後減少的.
FD
EDFA、和 EA 指定是滿棧還是空棧,是升序棧還是降序棧.
對於存儲STM而言
先加後存 FA 姑且這麼來記,先加(first add),存數據
後加先存 EA 姑且這麼來記,存數據,後加end add
先減後存 FD 姑且這麼來記,先減first dec,存數據
後減先存 ED 姑且這麼來記,存數據,後減end dec
然後記憶LDM,LDMSTM的反相彈出動作,所以
因爲是先加後存,所以後減先取 FA 就成了與STM對應的取數據,後減
因爲是後加先存,所以先減後取 EA 就成了與STM對應的先減,取數據
因爲是先減後存,所以後加先取 FD 就成了與STM對應的取數據,後加
因爲是後減先存,所以先加後取 ED 就成了與STM對應的先加,取數據
我想通過上面的變態方式可以比較容易的記住這套指令[gliethttp]
一個滿棧的棧指針指向上次寫的最後一個數據單元,而空棧的棧指針指向第一個空閒單元.
一個降序棧是在內存中反向增長(就是說,從應用程序空間結束處開始反向增長)而升序棧在內存中正向增長. 
其他形式簡單的描述指令的行爲,意思分別是
IA
過後增加(Increment After)
IB
預先增加(Increment Before)
DA
過後減少(Decrement After)
DB
預先減少(Decrement Before).

RISC OS使用傳統的滿降序棧.在使用符合APCS規定的編譯器的時候,它通常把你的棧指針設置在應用程序空間的
結束處並接着使用一個FD(滿降序-Full Descending).如果你與一個高級語言(BASICC)一起工作,你將別無選擇.
棧指針(傳統上是R13)指向一個滿降序棧.你必須繼續這個格式,或則建立並管理你自己的棧.
-----------------------------
4.
teq r1,#0      //r1-0,
將結果送入狀態標誌,如果r10相減的結果爲0,那麼ALUZ置位,否則Z0
bne reschedule//ne
表示Z0,:不等,那麼執行reschedule函數
-----------------------------
5.
使用tst來檢查是否設置了特定的位
tst r1,#0x80 //
按位and操作,檢測r10x1<<7,即第7位是否置1,按位與之後結果爲0,那麼ALUZ置位
beq reset    //
如果Z置位,:以上按位與操作結果是0,那麼跳轉到reset標號執行
-----------------------------
6.'^'
的理解
'^'
是一個後綴標誌,不能在User模式和Sys系統模式下使用該標誌.該標誌有兩個存在目的:
6.1.
對於LDM操作,同時恢復的寄存器中含有pc(r15)寄存器,那麼指令執行的同時cpu自動將spsr拷貝到cpsr
:IRQ中斷返回代碼中[如下爲ads環境下的代碼gliethttp]
ldmfd {r4}           //
讀取sp中保存的的spsr值到r4
msr spsr_cxsf,r4     //
spsr的所有控制爲進行寫操作,r4的值全部注入spsr
ldmfd {r0-r12,lr,pc}^//
當指令執行完畢,pc跳轉之前,spsr的值自動拷貝到cpsr[gliethttp]
6.2.
數據的送入、送出發生在User用戶模式下的寄存器,而非當前模式寄存器
:ldmdb sp,{r0 - lr}^;表示sp棧中的數據回覆到User分組寄存器r0-lr,而不是恢復到當前模式寄存器r0-lr
當然對於User,System,IRQ,SVC,Abort,Undefined6種模式來說[gliethttp]r0-r12是共用的,只是r13r14
  
爲分別獨有,對於FIQ模式,僅僅r0-r7是和前6中模式的r0-r7共用,r8-r14都是FIQ模式下專有.


-----------------------------
7.spsr_cxsf,cpsr_cxsf
的理解
c
control field maskbyte(PSR[7:0])
x
extension field maskbyte(PSR[15:8])
s
status field maskbyte(PSR[23:16)
f
flags field maskbyte(PSR[31:24]).
老式聲明方式:cpsr_flg,cpsr_allADS中已經不在支持
cpsr_flg
對應cpsr_f
cpsr_all
對應cpsr_cxsf

需要使用專用指令對cpsrspsr操作:mrs,msr
mrs tmp,cpsr      //
讀取CPSR的值
bic tmp,tmp,#0x80 //
如果第7位爲1,將其清0
msr cpsr_c,tmp    //
對控制位區psr[7:0]進行寫操作
-----------------------------
8.cpsr
的理解
CPSR = Current Program Status Register
SPSR = Saved Program Status Registers
CPSR
寄存器(和保存它的SPSR寄存器)


(
上圖)
N,Z,C,V
稱爲ALU狀態標誌
N:
如果結果是負數則置位
Z:
如果結果是零則置位
C:
如果發生進位則置位
V:
如果發生溢出則置位
I:
置位表示禁用IRQ中斷,0表示使能IRQ
F:
置位表示禁用FIQ中斷,0表示使能FIQ
T:
置位表示系統運行在Thumb,0表示運行在ARM
M[4:0]:
10000 User
模式,System系統模式一樣
10001 FIQ
模式
10010 IRQ
模式
10011 SVC
超級管理模式
10111 Abort
數據異常模式
11011 Undefined
未定義指令模式
11111 System
系統模式,User模式一樣

舉例:
ands r2,r2,#7
使用運算結果改變標誌位,如果運算結果r2=0,那麼Z置位,EQ相等判斷成立
subs r2,r2,#1
使用運算結果改變標誌位,如果運算結果r2=0,那麼Z置位,EQ相等判斷成立
beq wordcopy
-----------------------------
9.
指令後綴和條件判斷


(
上圖)
EQ :
等於
NE :
不等
CS :
無符號>=
CC :
無符號<
MI :
負數
PL :
非負[>=0]
VS :
溢出
VC :
無溢出
HI :
無符號>
LS :
無符號<=
GE :
有符號>=
LT :
有符號<
GT :
有符號>
LE :
有符號<=
AL :
總是[默認]

對於arm彙編指令,可以參考linux內核的arch/arm目錄,那裏的彙編指令很豐富[gliethttp_20080603]
__CopyFromStart
 
;    ldr     r3, [r9],#4     
 
;    str     r3, [r7], #4  
 
;    sub        r8, r8, #4
 
    ldrb    r3, [r9], #1
 
    strb    r3, [r7], #1
    sub     r8, r8, #1
    cmp        r8, #0
    bgt        __CopyFromStart
 
    b        __JumpToBootImage

__JumpToBootImage
    MOV     pc, r0

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章