注意:彙編語言下操作所有的資料必須取出資料放到通用寄存器中處理,完畢之後從通用寄存器中讀取出放到指定的寄存器中。
1.彙程式設計式書寫格式
聲明程式段時不要頂格寫。如下:
AREA test ,CODE,READONLY ;聲明代碼段 段名,類型,屬性
ENTRY 程式的入口(可以沒有如果有隻能是一個,告訴編譯器後面的代碼段不用優化)
CODE32 下面的指令為ARM指令集 如果是thumb應該是CODE16
MAIN (标簽,可以了解為C語言的函數名,必須頂格寫)
move r0,#0x1;
b .
上面的彙編代碼為:聲明了一段test的彙編代碼,類型為代碼(CODE),屬性為隻讀(READONLY)。指定了程式入口且說明用到的指令為ARM指令集(CODE32)。
2.arm指令集
3.arm常用指令
分支指令:b、bl
資料處理指令隻能對寄存器的内容進行操作,不能對存儲器操作,可細分為4類
資料傳送指令:mov,mvn
算術運算指令:add,adc,sub,sbc,rsb,rsc
邏輯運算指令:and,orr,eor,bic
比較指令:cmp,cmn,tst,teq
乘法指令,僅為兩個寄存器相乘(寄存器直接尋址,不涉及存儲器):mul,mla
狀态寄存器通路指令:msr,mrs
單寄存器加載/存儲指令(主要用于通路外部裝置):ldr,str
多寄存器加載/存儲指令
信号量(交換)指令(用于程序間的同步):swp,swpb
異常産生指令
協處理器指令:cdp,ldc,stc,mcr,mrc
ARM僞指令:adr,adrl,ldr,nop
4.arm指令中常用到的條件碼
條件助記符: EQ NE CS/HS CC/LO HI LS
标志: Z=1 Z=0 C=1 C=0 C=1,Z=0 C=0,Z=1
含義: 相等 不相等 無符号數大于 無符号數小于
或等于
5.b,bl指令差別:
B或BL指令引起處理器轉移到“子程式名”處開始執行。兩者的不同之處在于BL指令在轉移到子程式執行之前,将其下一條指令的位址拷貝到R14(LR,連結寄存器)。由于BL指令儲存了下條指令的位址,是以使用指令“MOV PC ,LR”即可實作子程式的傳回。而B指令則無法實作子程式的傳回,隻能實作單純的跳轉。使用者在程式設計的時候,可根據具體應用選用合适的子程式調用語句。
AREA Init,CODE,READONLY ;該僞指令定義了一個代碼段,段名為Init,屬性隻讀
ENTRY ;程式的入口點辨別
.
.
bl delay ;調用延遲
.
.
mov pc,lr ;傳回
6.arm彙編指令的一點總結
比較有用的是MOV B BL LDR STR,如下代碼:
@ disable watch dog timer mov r1, #0x53000000 //立即數尋址方式
mov r2, #0x0
str r2, [r1]
立即數尋址方式,立即數要求以“#”作字首,對于十六進制的數,還要求在#後面加上0x或者&。STR是比較重要的指令,跟它對應的是LDR。ARM指令集是加載/存儲型的,也就是說它隻處理在寄存器中的資料。那麼對于系統存儲器的通路就經常用到STR和LDR了。STR是把寄存器上的資料傳輸到指定位址的存儲器上。它的格式有點特殊: STR(條件) 源寄存器,
比如 STR R0, [R1] ,意思是R0-> [R1],它把源寄存器寫在前面,跟MOV、LDR都相反。
LDR應該是非常常見了。LDR就是把資料從存儲器傳輸到寄存器上。而且有個僞指令也是LDR,是以我有個百思不得其解的問題。看這段代碼:
mov r1, #GPIO_CTL_BASE
add r1, r1, #oGPIO_F
ldr r2,=0x55aa // 0x55aa是個立即數啊,前面加個=幹什麼?
對于當中的ldr 那句,我就不明白了,如果你把=去掉,是不能通過編譯的。查了一些資料,個人感覺為:這個=應該表示LDR不是ARM指令,而是僞指令。作為僞指令的時候,LDR的格式如下:
LDR 寄存器, =數字常量/Label
它的作用是把一個32位的位址或者常量調入寄存器。嗬嗬,那大家可能會問,
“MOV r2,#0x55aa”也可以啊。應該是這樣的。不過,LDR是僞指令啊,也就是說編譯時編譯器會處理它的。怎麼處理的呢?——規則如下:如果該數字常量在MOV指令範圍内,彙編器會把這個指令作為MOV。如果不在MOV範圍中,彙編器把該常量放在程式後面,用LDR來讀取,PC和該常量的偏移量不能超過 4KB。
然後說一下跳轉指令。ARM有兩種跳轉方式。 (1) mov pc