資料介紹
第一部分 Linux下ARM匯編語法盡管在Linux下使用C或C++編寫程序很方便,但匯編源程序用于系統(tǒng)最基本的初始化,如初始化堆棧指針、設置頁表、操作 ARM的協(xié)處理器等。初始化完成后就可以跳轉到C代碼執(zhí)行。需要注意的是,GNU的匯編器遵循AT&T的匯編語法,可以從GNU的站點(www.gnu.org)上下載有關規(guī)范。
一. Linux匯編行結構
任何匯編行都是如下結構:
[:] [} @ comment
[:] [} @ 注釋
Linux ARM 匯編中,任何以冒號結尾的標識符都被認為是一個標號,而不一定非要在一行的開始。
【例1】定義一個"add"的函數(shù),返回兩個參數(shù)的和。
.section .text, “x”
.global add @ give the symbol add external linkage
add:
ADD r0, r0, r1 @ add input arguments
MOV pc, lr @ return from subroutine
@ end of program
二. Linux 匯編程序中的標號
標號只能由a~z,A~Z,0~9,“.”,_等字符組成。當標號為0~9的數(shù)字時為局部標號,局部標號可以重復出現(xiàn),使用方法如下:
標號f: 在引用的地方向前的標號
標號b: 在引用的地方向后的標號
【例2】使用局部符號的例子,一段循環(huán)程序
1:
??subs r0,r0,#1 @每次循環(huán)使r0=r0-1
??bne 1f @跳轉到1標號去執(zhí)行
局部標號代表它所在的地址,因此也可以當作變量或者函數(shù)來使用。
三. Linux匯編程序中的分段
(1).section偽操作
用戶可以通過.section偽操作來自定義一個段,格式如下:
.section section_name [, "flags"[, %type[,flag_specific_arguments]]]
每一個段以段名為開始, 以下一個段名或者文件結尾為結束。這些段都有缺省的標志(flags),連接器可以識別這些標志。(與armasm中的AREA相同)。
下面是ELF格式允許的段標志
含義
a 允許段
w 可寫段
x 執(zhí)行段
【例3】定義段
.section .mysection @自定義數(shù)據(jù)段,段名為 “.mysection”
.align 2
strtemp:
.ascii "Temp string \n\0"
(2)匯編系統(tǒng)預定義的段名
.text @代碼段
.data @初始化數(shù)據(jù)段
.bss @未初始化數(shù)據(jù)段
.sdata @
.sbss @
需要注意的是,源程序中.bss段應該在.text之前。
四. 定義入口點
匯編程序的缺省入口是 start標號,用戶也可以在連接腳本文件中用ENTRY標志指明其它入口點。
【例4】定義入口點
.section.data
.section .bss
.section .text
.globl _start
_start:
五. Linux匯編程序中的宏定義
格式如下:
.macro 宏名 參數(shù)名列表 @偽指令.macro定義一個宏
??宏體
.endm @.endm表示宏結束
如果宏使用參數(shù),那么在宏體中使用該參數(shù)時添加前綴“\”。宏定義時的參數(shù)還可以使用默認值。
可以使用.exitm偽指令來退出宏。
【例5】宏定義
.macro SHIFTLEFT a, b
.if \b ”表示不相等,其他的符號如:+、-、*、 /、%、、>>、|、&、^、!、==、>=、函數(shù)的定義 ;
對齊方式偽操作 .align;
源文件結束偽操作.end;
.include偽操作;
if偽操作;
.global/ .globl 偽操作 ;
.type偽操作 ;
列表控制語句 ;
區(qū)別于gas匯編的通用偽操作,下面是ARM特有的偽操作 :.reg ,.unreq ,.code ,.thumb ,.thumb_func ,.thumb_set, .ltorg ,.pool
1. 數(shù)據(jù)定義偽操作
(1) .byte:單字節(jié)定義,如:.byte 1,2,0b01,0x34,072,'s' ;
(2) .short:定義雙字節(jié)數(shù)據(jù),如:.short 0x1234,60000 ;
(3) .long:定義4字節(jié)數(shù)據(jù),如:.long 0x12345678,23876565
(4) .quad:定義8字節(jié),如:.quad 0x1234567890abcd
(5) .float:定義浮點數(shù),如:
??.float 0f-314159265358979323846264338327\
??95028841971.693993751E-40 @ - pi
(6) .string/.asciz/.ascii:定義多個字符串,如:
??.string "abcd", "efgh", "hello!"
??.asciz "qwer", "sun", "world!"
??.ascii "welcome\0"
需要注意的是:.ascii偽操作定義的字符串需要自行添加結尾字符'\0'。
(7) .rept:重復定義偽操作, 格式如下:
??.rept 重復次數(shù)
??數(shù)據(jù)定義
??.endr @結束重復定義
??例如:
??.rept 3
??.byte 0x23
??.endr
(8) .equ/.set: 賦值語句, 格式如下:
??.equ(.set) 變量名,表達式
??例如:
??.equ abc 3 @讓abc=3
2.函數(shù)的定義偽操作
(1)函數(shù)的定義,格式如下:
??函數(shù)名:
??函數(shù)體
??返回語句
一般的,函數(shù)如果需要在其他文件中調用, 需要用到.global偽操作將函數(shù)聲明為全局函數(shù)。為了不至于在其他程序在調用某個C函數(shù)時發(fā)生混亂,對寄存器的使用我們需要遵循APCS準則。函數(shù)編譯器將處理為函數(shù)代碼為一段.global的匯編碼。
(2)函數(shù)的編寫應當遵循如下規(guī)則:
a1-a4寄存器(參數(shù)、結果或暫存寄存器,r0到r3 的同義字)以及浮點寄存器f0-f3(如果存在浮點協(xié)處理器)在函數(shù)中是不必保存的;
如果函數(shù)返回一個不大于一個字大小的值,則在函數(shù)結束時應該把這個值送到 r0 中;
如果函數(shù)返回一個浮點數(shù),則在函數(shù)結束時把它放入浮點寄存器f0中;
如果函數(shù)的過程改動了sp(堆棧指針,r13)、fp(框架指針,r11)、sl(堆棧限制,r10)、lr(連接寄存器,r14)、v1-v8(變量寄存器,r4 到 r11)和 f4-f7,那么函數(shù)結束時這些寄存器應當被恢復為包含在進入函數(shù)時它所持有的值。
3. .align .end .include .incbin偽操作
(1).align:用來指定數(shù)據(jù)的對齊方式,格式如下:
??.align [absexpr1, absexpr2]
??以某種對齊方式,在未使用的存儲區(qū)域填充值. 第一個值表示對齊方式,4, 8,16或 32. 第二個表達式值表示填充的值。
(2).end:表明源文件的結束。
(3).include:可以將指定的文件在使用.include 的地方展開,一般是頭文件,例如:
??.include “myarmasm.h”
(4).incbin偽操作可以將原封不動的一個二進制文件編譯到當前文件中,使用方法如下:
??.incbin "file"[,skip[,count]]
??skip表明是從文件開始跳過skip個字節(jié)開始讀取文件,count是讀取的字數(shù).
4. .if偽操作
根據(jù)一個表達式的值來決定是否要編譯下面的代碼, 用.endif偽操作來表示條件判斷的結束, 中間可以使用.else來決定.if的條件不滿足的情況下應該編譯哪一部分代碼。
.if有多個變種:
.ifdef symbol @判斷symbol是否定義
.ifc string1,string2 @字符串string1和string2是否相等,字符串可以用單引號括起來
.ifeq expression_r @判斷expression_r的值是否為0
.ifeqs string1,string2 @判斷string1和string2是否相等,字符 串必須用雙引號括起來
.ifge expression_r @判斷expression_r的值是否大于等于0
.ifgt absolute expression_r @判斷expression_r的值是否大于0
.ifle expression_r @判斷expression_r的值是否小于等于0
.iflt absolute expression_r @判斷expression_r的值是否小于0
.ifnc string1,string2 @判斷string1和string2是否不相等, 其用法跟.ifc恰好相反。
.ifndef symbol, .ifnotdef symbol @判斷是否沒有定義symbol, 跟.ifdef恰好相反
.ifne expression_r @如果expression_r的值不是0, 那么編譯器將編譯下面的代碼
.ifnes string1,string2 @如果字符串string1和string2不相 等, 那么編譯器將編譯下面的代碼.
5. .global .type .title .list
(1).global/ .globl :用來定義一個全局的符號,格式如下:
??.global symbol 或者 .globl symbol
(2).type:用來指定一個符號的類型是函數(shù)類型或者是對象類型, 對象類型一般是數(shù)據(jù), 格式如下:
??.type 符號, 類型描述
【例6】
.globl a
.data
.align 4
.type a, @object
.size a, 4
a:
.long 10
【例7】
.section .text
.type asmfunc, @function
.globl asmfunc
asmfunc:
mov pc, lr
(3)列表控制語句:
.title:用來指定匯編列表的標題,例如:
??.title “my program”
.list:用來輸出列表文件.
6. ARM特有的偽操作
(1) .reg: 用來給寄存器賦予別名,格式如下:
??別名 .req 寄存器名
(2) .unreq: 用來取消一個寄存器的別名,格式如下:
.unreq 寄存器別名
注意被取消的別名必須事先定義過,否則編譯器就會報錯,這個偽操作也可以用來取消系統(tǒng)預制的別名, 例如r0, 但如果沒有必要的話不推薦那樣做。
(3) .code偽操作用來選擇ARM或者Thumb指令集,格式如下:
.code 表達式
如果表達式的值為16則表明下面的指令為Thumb指令,如果表達式的值為32則表明下面的指令為ARM指令.
(4) .thumb偽操作等同于.code 16, 表明使用Thumb指令, 類似的.arm等同于.code 32
(5) .force_thumb偽操作用來強制目標處理器選擇thumb的指令集而不管處理器是否支持
(6) .thumb_func偽操作用來指明一個函數(shù)是thumb指令集的函數(shù)
(7) .thumb_set偽操作的作用類似于.set, 可以用來給一個標志起一個別名, 比.set功能增加的一點是可以把一個標志標記為thumb函數(shù)的入口, 這點功能等同于.thumb_func
(8) .ltorg用于聲明一個數(shù)據(jù)緩沖池(literal pool)的開始,它可以分配很大的空間。
(9) .pool的作用等同.ltorg
(9).space??{,}
分配number_of_bytes字節(jié)的數(shù)據(jù)空間,并填充其值為fill_byte,若未指定該值,缺省填充0。(與armasm中的SPACE功能相同)
(10).word??{,} …
插入一個32-bit的數(shù)據(jù)隊列。(與armasm中的DCD功能相同)
可以使用.word把標識符作為常量使用
例如:
??Start:
??valueOfStart:
??.word Start
這樣程序的開頭Start便被存入了內存變量valueOfStart中。
(11).hword??{,} …
插入一個16-bit的數(shù)據(jù)隊列。(與armasm中的DCW相同)
八. GNU ARM匯編特殊字符和語法
代碼行中的注釋符號: ‘@’
整行注釋符號: ‘#’
語句分離符號: ‘;’
直接操作數(shù)前綴: ‘#’ 或 ‘$’
第二部分 GNU的編譯器和調試工具
一. 編譯工具
1.編輯工具介紹
GNU 提供的編譯工具包括匯編器as、C編譯器gcc、C++編譯器g++、連接器ld和二進制轉換工具objcopy?;贏RM平臺的工具分別為arm- linux-as、arm-linux-gcc、arm-linux-g++、arm-linux-ld和arm-linux- objcopy。GNU的編譯器功能非常強大,共有上百個操作選項,這也是這類工具讓初學者頭痛的原因。不過,實際開發(fā)中只需要用到有限的幾個,大部分可以采用缺省選項。GNU工具的開發(fā)流程如下:編寫C、C++語言或匯編源程序,用gcc或g++生成目標文件,編寫連接腳本文件,用連接器生成最終目標文件(elf格式),用二進制轉換工具生成可下載的二進制代碼。
(1)編寫C、C++語言或匯編源程序
通常匯編源程序用于系統(tǒng)最基本的初始化,如初始化堆棧指針、設置頁表、操作ARM的協(xié)處理器等。初始化完成后就可以跳轉到C代碼執(zhí)行。需要注意的是,GNU的匯編器遵循AT&T的匯編語法,讀者可以從GNU的站點(www.gnu.org)上下載有關規(guī)范。匯編程序的缺省入口是 start標號,用戶也可以在連接腳本文件中用ENTRY標志指明其它入口點(見下文關于連接腳本的說明)。
(2)用gcc或g++生成目標文件
如果應用程序包括多個文件,就需要進行分別編譯,最后用連接器連接起來。如筆者的引導程序包括3個文件:init.s(匯編代碼、初始化硬件)xmrecever.c(通信模塊,采用Xmode協(xié)議)和flash.c(Flash擦寫模塊)。
分別用如下命令生成目標文件: arm-linux-gcc-c-O2-oinit.oinit.s arm-linux-gcc-c-O2-oxmrecever.oxmrecever.c arm-linux-gcc-c-O2-oflash.oflash.c 其中-c命令表示只生成目標代碼,不進行連接;-o命令指明目標文件的名稱;-O2表示采用二級優(yōu)化,采用優(yōu)化后可使生成的代碼更短,運行速度更快。如果項目包含很多文件,則需要編寫makefile文件。關于makefile的內容,請感興趣的讀者參考相關資料。
(3)編寫連接腳本文件
gcc 等編譯器內置有缺省的連接腳本。如果采用缺省腳本,則生成的目標代碼需要操作系統(tǒng)才能加載運行。為了能在嵌入式系統(tǒng)上直接運行,需要編寫自己的連接腳本文件。編寫連接腳本,首先要對目標文件的格式有一定了解。GNU編譯器生成的目標文件缺省為elf格式。elf文件由若干段(section)組成,如不特殊指明,由C源程序生成的目標代碼中包含如下段:.text(正文段)包含程序的指令代碼;.data(數(shù)據(jù)段)包含固定的數(shù)據(jù),如常量、字符串;.bss(未初始化數(shù)據(jù)段)包含未初始化的變量、數(shù)組等。C++源程序生成的目標代碼中還包括.fini(析構函數(shù)代碼)和. init(構造函數(shù)代碼)等。連接器的任務就是將多個目標文件的.text、.data和.bss等段連接在一起,而連接腳本文件是告訴連接器從什么地址開始放置這些段。例如連接文件link.lds為:
ENTRY(begin)
SECTION
{
.=0x30000000;
.text:{*(.text)}
.data:{*(.data)}
.bss:{*(.bss)}
}
其中,ENTRY(begin)指明程序的入口點為begin標號;.=0x00300000指明目標代碼的起始地址為0x30000000,這一段地址為 MX1的片內RAM;.text:{*(.text)}表示從0x30000000開始放置所有目標文件的代碼段,隨后的.data:{* (.data)}表示數(shù)據(jù)段從代碼段的末尾開始,再后是.bss段。
(4)用連接器生成最終目標文件
有了連接腳本文件,如下命令可生成最終的目標文件:
arm-linux-ld –no stadlib –o bootstrap.elf -Tlink.lds init.o xmrecever.o flash.o
其中,ostadlib表示不連接系統(tǒng)的運行庫,而是直接從begin入口;-o指明目標文件的名稱;-T指明采用的連接腳本文件(也可以使用-Ttext address,address表示執(zhí)行區(qū)地址);最后是需要連接的目標文件列表。
(5)生成二進制代碼
連接生成的elf文件還不能直接下載執(zhí)行,通過objcopy工具可生成最終的二進制文件:
arm-linux-objcopy –O binary bootstrap.elf bootstrap.bin
其中-O binary指定生成為二進制格式文件。Objcopy還可以生成S格式的文件,只需將參數(shù)換成-O srec。還可以使用-S選項,移除所有的符號信息及重定位信息。如果想將生成的目標代碼反匯編,還可以用objdump工具:
arm-linux-objdump -D bootstrap.elf
至此,所生成的目標文件就可以直接寫入Flash中運行了。
2.Makefile實例
example: head.s main.c
arm-linux-gcc -c -o head.o head.s
arm-linux-gcc -c -o main.o main.c
arm-linux-ld -Tlink.lds head.o ain.o -o example.elf
arm-linux-objcopy -O binary -S example_tmp.o example
arm-linux-objdump -D -b binary -m arm example >ttt.s
二. 調試工具
Linux 下的GNU調試工具主要是gdb、gdbserver和kgdb。其中gdb和gdbserver可完成對目標板上Linux下應用程序的遠程調試。 gdbserver是一個很小的應用程序,運行于目標板上,可監(jiān)控被調試進程的運行,并通過串口與上位機上的gdb通信。開發(fā)者可以通過上位機的gdb輸入命令,控制目標板上進程的運行,查看內存和寄存器的內容。gdb5.1.1以后的版本加入了對ARM處理器的支持,在初始化時加入- target==arm參數(shù)可直接生成基于ARM平臺的gdbserver。gdb工具可以從ftp: //ftp.gnu.org/pub/gnu/gdb/上下載。
對于Linux內核的調試,可以采用kgdb工具,同樣需要通過串口與上位機上的gdb通信,對目標板的Linux內核進行調試??梢詮膆ttp://oss.sgi.com/projects/kgdb/上了解具體的使用方法。
- 用GNU構建裸機系統(tǒng) 0次下載
- Eclipse替代keil - GNU ARM Eclipse Plugins即 GNU MCU Eclipse Plugins安裝
- ARM匯編語言的源程序免費下載 16次下載
- GNU匯編入門教程免費下載 20次下載
- ARM嵌入式處理器的GNU工具應用程序免費下載 7次下載
- GNU ARM匯編入門教程的詳細資料免費下載 15次下載
- 如何使用GNU語言工具來編寫16位單片機應用程序代碼的方法
- 如何使用GNU語言工具來為32位單片機應用編寫代碼的詳細中文資料概述
- ARM匯編語言工具V5.1用戶指南 6次下載
- ARM匯編編譯器的使用 5次下載
- GNU-ARM匯編程序設計 11次下載
- ARM標準匯編與GNU匯編大全
- arm匯編指令詳解
- 常用arm指令集及匯編
- 常用ARM指令集與匯編
- 軟件無線電安全之GNU Radio基礎知識 4944次閱讀
- 一文認識ARM匯編指令和體系架構 3023次閱讀
- 講講ARM指令集格式以及常用的ARM匯編指令 4056次閱讀
- 使用VSCODE+GNU+J-Link開發(fā)瑞薩RA MCU(上) 1116次閱讀
- GNU C語言的特性 809次閱讀
- GNU/Linux和Linux的區(qū)別在哪? 1690次閱讀
- 使用Eclipse插件調試AT32系列芯片 3028次閱讀
- 如何在KEIL下閱讀匯編 4037次閱讀
- 零基礎學ARM:匯編偽指令、lds詳解 2935次閱讀
- 淺談GNU 嵌入式匯編具體因使用方法 905次閱讀
- 拒絕開發(fā)板,?用 SkyEye 就可以模擬 ARM Linux! 1w次閱讀
- 學習ARM + Linux之前要講解用ADS或RealViewMDK去調試ARM開發(fā)板的原因 5923次閱讀
- arm的匯編指令精選合輯 2094次閱讀
- 單片機編程之匯編語言基礎-常用指令和程序模式 1.5w次閱讀
- 用GNU工具開發(fā)基于ARM的嵌入式系統(tǒng) 1708次閱讀
下載排行
本周
- 1電子電路原理第七版PDF電子教材免費下載
- 0.00 MB | 1490次下載 | 免費
- 2單片機典型實例介紹
- 18.19 MB | 92次下載 | 1 積分
- 3S7-200PLC編程實例詳細資料
- 1.17 MB | 27次下載 | 1 積分
- 4筆記本電腦主板的元件識別和講解說明
- 4.28 MB | 18次下載 | 4 積分
- 5開關電源原理及各功能電路詳解
- 0.38 MB | 10次下載 | 免費
- 6基于AT89C2051/4051單片機編程器的實驗
- 0.11 MB | 4次下載 | 免費
- 7藍牙設備在嵌入式領域的廣泛應用
- 0.63 MB | 3次下載 | 免費
- 89天練會電子電路識圖
- 5.91 MB | 3次下載 | 免費
本月
- 1OrCAD10.5下載OrCAD10.5中文版軟件
- 0.00 MB | 234313次下載 | 免費
- 2PADS 9.0 2009最新版 -下載
- 0.00 MB | 66304次下載 | 免費
- 3protel99下載protel99軟件下載(中文版)
- 0.00 MB | 51209次下載 | 免費
- 4LabView 8.0 專業(yè)版下載 (3CD完整版)
- 0.00 MB | 51043次下載 | 免費
- 5555集成電路應用800例(新編版)
- 0.00 MB | 33562次下載 | 免費
- 6接口電路圖大全
- 未知 | 30320次下載 | 免費
- 7Multisim 10下載Multisim 10 中文版
- 0.00 MB | 28588次下載 | 免費
- 8開關電源設計實例指南
- 未知 | 21539次下載 | 免費
總榜
- 1matlab軟件下載入口
- 未知 | 935053次下載 | 免費
- 2protel99se軟件下載(可英文版轉中文版)
- 78.1 MB | 537791次下載 | 免費
- 3MATLAB 7.1 下載 (含軟件介紹)
- 未知 | 420026次下載 | 免費
- 4OrCAD10.5下載OrCAD10.5中文版軟件
- 0.00 MB | 234313次下載 | 免費
- 5Altium DXP2002下載入口
- 未知 | 233045次下載 | 免費
- 6電路仿真軟件multisim 10.0免費下載
- 340992 | 191183次下載 | 免費
- 7十天學會AVR單片機與C語言視頻教程 下載
- 158M | 183277次下載 | 免費
- 8proe5.0野火版下載(中文版免費下載)
- 未知 | 138039次下載 | 免費
評論