第2課:ARM匯編學(xué)習(xí)
1通過(guò)學(xué)習(xí)ARM匯編語(yǔ)言從而了解ARM處理器的工作原理。
本文引用地址:http://butianyuan.cn/article/201611/316805.htm2用匯編寫(xiě)B(tài)ootloader
在這里匯編的基本語(yǔ)法在《ARM嵌入式系統(tǒng)開(kāi)發(fā)》里面已經(jīng)寫(xiě)過(guò)了。這里就寫(xiě)一點(diǎn)需要特別注意的地方
我們學(xué)匯編,并不是要求用匯編寫(xiě)很多復(fù)雜的程序。那樣不切實(shí)際,那些可以用更高一層的C來(lái)寫(xiě)。
7種尋址方式:
1立即數(shù)尋址 ADD r0,r0,#1
2寄存器尋址 ADD r0,r0,r1
3寄存器間接尋址 LDR r0,[r1]
4寄存器變址尋址 :前變址,自動(dòng)變址,后變址
LDR r0,[r1,#4]
LDR r0,[r1,#4]!
LDR r0,[r1],#4
5堆棧尋址 我們一般用FD 滿遞減 LDM {sp}!,{r1-r4}
只用于堆棧
6塊拷貝尋址
LDMIA LDMIB LDMDA LDMDB
7相對(duì)尋址
BL label 相對(duì)地址的尋址
LDR pc,label 或 MOV pc,label 絕對(duì)地址的尋址
具體指令不再做介紹了。補(bǔ)充一些:
1在例如 LDMFD sp?。鹯1-r5,pc}^
在加了pc的情況下 再加^表示把spsr拷貝到cpsr中。
2乘法指令一般不太用,效率低。即使要用也用位移來(lái)代替。
3AND與 用來(lái)志零 ORR或用來(lái)志1 EOR異或用來(lái)取反 BIC用來(lái)清位(BIC是比較數(shù)的哪一位是1哪一位就變0與AND相反)
而TST是沒(méi)有結(jié)果寄存器的AND 并且改變cpsr TEQ是異或 CMP是減法。
接下來(lái)說(shuō)本課的重點(diǎn) armlinux的編譯器gcc
在win下面用的是armcc,而我們的用gcc
1任何以冒號(hào)結(jié)尾的標(biāo)識(shí)符都認(rèn)為是一個(gè)標(biāo)號(hào),當(dāng)標(biāo)號(hào)為0到9的數(shù)字時(shí)是局部標(biāo)號(hào)。在局部標(biāo)號(hào)后加f表示引用標(biāo)號(hào)的地方向前的標(biāo)號(hào)
而加b則表示向后
例如: subs r0,r0,#1
bne 1f
2 。section偽操作來(lái)定義一個(gè)段,后加段名
匯編系統(tǒng)有預(yù)定義的段名 。text 代碼段 。data初始化數(shù)據(jù)段 。bss未初始化數(shù)據(jù)段 (。bss要在text之前)
3定義入口點(diǎn),默認(rèn)下是start標(biāo)號(hào),也可以在連接腳本中用ENTRY(標(biāo)志)來(lái)指示入口標(biāo)志。連接腳本之后介紹。
.section .data
<...>
.section .bss
<...>
.section.text
.globl _start _start是全局的
_start:代碼從這開(kāi)始執(zhí)行。
4. .align 2(4,8,16) 對(duì)齊方式
.end 結(jié)束符 不加也不報(bào)錯(cuò)
.include 包含頭文件
.global 定義一個(gè)全局符號(hào)
編譯器 5大工具
arm-linux-as
arm-linux-gcc
arm-linux-ld
arm-linux-objcopy
arm-linux-objdump
介紹下一個(gè)ARM程序誕生的步驟。
1寫(xiě)程序
2編譯成.o文件 用arm-linux-gcc -c link.s -o link.o
如果使用-S選項(xiàng) 對(duì)用C寫(xiě)的程序表示編譯生成匯編文件
3編寫(xiě)連接腳本,編譯成elf格式的文件:首先明確為什么要連接:有2點(diǎn),1地址重定向。2寫(xiě)符號(hào)表。在gcc編譯器中有內(nèi)置的缺省的連接腳本,不過(guò)它是基于有操作系統(tǒng)的前提下的才能應(yīng)用加載的。因?yàn)樗菓?yīng)用操作系統(tǒng)中內(nèi)存的映射地址來(lái)連接的。而gnu編譯器目標(biāo)文件的個(gè)是是elf格式。它由若干的section組成。里面有。text段。data段。bss段。連接器的任務(wù)就是把多個(gè)目標(biāo)文件的。text段。data段。bss段連接在一起。而連接腳本是告訴連接器從什么地址開(kāi)始放至這些段。
如link。lds
ENTRY(begin)
SECTION
{
.=0x30000000; 表示目標(biāo)代碼開(kāi)始的地址為0x30000000
.text :{*(.text)}
.data :{*(.data)}
.bss :{*(.bss)}
}
然后通過(guò)arm-linux-ld -nostadlib -o link.elf -Tlink.lds link.o main.o 生成elf格式的文件。其中nostadlib表示不連接系統(tǒng)的庫(kù),-T表示采用連接腳本。也可以使用-Ttext address;address表示執(zhí)行區(qū)地址。
4生成2進(jìn)制文件。2進(jìn)制文件才可以在內(nèi)存中加載
arm-linux-objcopy -o link.bin link.elf
5反匯編
還可以用objdump來(lái)實(shí)現(xiàn)反匯編
arm-linux-objdump -D link.elf > a.dis
arm-linux-objdump -D -b binary-m arm link.bin >a.dis
評(píng)論