GCC-ARM匯編.docx_第1頁
GCC-ARM匯編.docx_第2頁
GCC-ARM匯編.docx_第3頁
GCC-ARM匯編.docx_第4頁
GCC-ARM匯編.docx_第5頁
已閱讀5頁,還剩11頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

標(biāo)簽: GNU ASM GNU-ARM 匯編指令第一部分 Linux下ARM匯編語法盡管在Linux下使用C或C+編寫程序很方便,但匯編源程序用于系統(tǒng)最基本的初始化,如初始化堆棧指針、設(shè)置頁表、操作 ARM的協(xié)處理器等。初始化完成后就可以跳轉(zhuǎn)到C代碼執(zhí)行。需要注意的是,GNU的匯編器遵循AT&T的匯編語法,可以從GNU的站點(diǎn)()上下載有關(guān)規(guī)范。一. Linux匯編行結(jié)構(gòu)任何匯編行都是如下結(jié)構(gòu):: comment: 注釋Linux ARM 匯編中,任何以冒號結(jié)尾的標(biāo)識符都被認(rèn)為是一個標(biāo)號,而不一定非要在一行的開始?!纠?】定義一個add的函數(shù),返回兩個參數(shù)的和。.section .text, “x”.global add give the symbol add external linkageadd:ADD r0, r0, r1 add input argumentsMOV pc, lr return from subroutine end of program二. Linux 匯編程序中的標(biāo)號標(biāo)號只能由az,AZ,09,“.”,_等字符組成。當(dāng)標(biāo)號為09的數(shù)字時(shí)為局部標(biāo)號,局部標(biāo)號可以重復(fù)出現(xiàn),使用方法如下:標(biāo)號f: 在引用的地方向前的標(biāo)號標(biāo)號b: 在引用的地方向后的標(biāo)號【例2】使用局部符號的例子,一段循環(huán)程序1: subs r0,r0,#1 每次循環(huán)使r0=r0-1 bne 1f 跳轉(zhuǎn)到1標(biāo)號去執(zhí)行局部標(biāo)號代表它所在的地址,因此也可以當(dāng)作變量或者函數(shù)來使用。三. Linux匯編程序中的分段(1).section偽操作用戶可以通過.section偽操作來自定義一個段,格式如下: .section section_name , flags, %type,flag_specific_arguments每一個段以段名為開始, 以下一個段名或者文件結(jié)尾為結(jié)束。這些段都有缺省的標(biāo)志(flags),連接器可以識別這些標(biāo)志。(與armasm中的AREA相同)。下面是ELF格式允許的段標(biāo)志 含義a 允許段w 可寫段x 執(zhí)行段【例3】定義段 .section .mysection 自定義數(shù)據(jù)段,段名為 “.mysection” .align 2 strtemp: .ascii Temp string n0(2)匯編系統(tǒng)預(yù)定義的段名.text 代碼段.data 初始化數(shù)據(jù)段.bss 未初始化數(shù)據(jù)段.sdata .sbss 需要注意的是,源程序中.bss段應(yīng)該在.text之前。四. 定義入口點(diǎn)匯編程序的缺省入口是 start標(biāo)號,用戶也可以在連接腳本文件中用ENTRY標(biāo)志指明其它入口點(diǎn)?!纠?】定義入口點(diǎn).section.data.section .bss.section .text.globl _start_start:五. Linux匯編程序中的宏定義格式如下: .macro 宏名 參數(shù)名列表 偽指令.macro定義一個宏 宏體 .endm .endm表示宏結(jié)束如果宏使用參數(shù),那么在宏體中使用該參數(shù)時(shí)添加前綴“”。宏定義時(shí)的參數(shù)還可以使用默認(rèn)值。可以使用.exitm偽指令來退出宏?!纠?】宏定義.macro SHIFTLEFT a, b.if b 0MOV a, a, ASR #-b.exitm.endifMOV a, a, LSL #b.endm六. Linux匯編程序中的常數(shù)(1)十進(jìn)制數(shù)以非0數(shù)字開頭,如:123和9876;(2)二進(jìn)制數(shù)以0b開頭,其中字母也可以為大寫;(3)八進(jìn)制數(shù)以0開始,如:0456,0123;(4)十六進(jìn)制數(shù)以0x開頭,如:0xabcd,0X123f;(5)字符串常量需要用引號括起來,中間也可以使用轉(zhuǎn)義字符,如: “You are welcome!n”;(6)當(dāng)前地址以“.”表示,在匯編程序中可以使用這個符號代表當(dāng)前指令的地址;(7)表達(dá)式:在匯編程序中的表達(dá)式可以使用常數(shù)或者數(shù)值, “-”表示取負(fù)數(shù), “”表示取補(bǔ),“”表示不相等,其他的符號如:+、-、*、 /、%、|、&、!、=、=、=、&、| 跟C語言中的用法相似。七. Linux下ARM匯編的常用偽操作在前面已經(jīng)提到過了一些為操作,還有下面一些為操作:數(shù)據(jù)定義偽操作: .byte,.short,.long,.quad,.float,.string/.asciz/.ascii,重復(fù)定義偽操作.rept,賦值語句.equ/.set ; 函數(shù)的定義 ; 對齊方式偽操作 .align; 源文件結(jié)束偽操作.end;.include偽操作; if偽操作; .global/ .globl 偽操作 ;.type偽操作 ;列表控制語句 ;區(qū)別于gas匯編的通用偽操作,下面是ARM特有的偽操作 :.reg ,.unreq ,.code ,.thumb ,.thumb_func ,.thumb_set, .ltorg ,.pool1. 數(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:定義浮點(diǎn)數(shù),如: .float 0f-314159265358979323846264338327 95028841971.693993751E-40 - pi(6) .string/.asciz/.ascii:定義多個字符串,如: .string abcd, efgh, hello! .asciz qwer, sun, world! .ascii welcome0需要注意的是:.ascii偽操作定義的字符串需要自行添加結(jié)尾字符0。(7) .rept:重復(fù)定義偽操作, 格式如下: .rept 重復(fù)次數(shù) 數(shù)據(jù)定義 .endr 結(jié)束重復(fù)定義 例如: .rept 3 .byte 0x23 .endr(8) .equ/.set: 賦值語句, 格式如下: .equ(.set) 變量名,表達(dá)式 例如: .equ abc 3 讓abc=32.函數(shù)的定義偽操作(1)函數(shù)的定義,格式如下: 函數(shù)名: 函數(shù)體 返回語句一般的,函數(shù)如果需要在其他文件中調(diào)用, 需要用到.global偽操作將函數(shù)聲明為全局函數(shù)。為了不至于在其他程序在調(diào)用某個C函數(shù)時(shí)發(fā)生混亂,對寄存器的使用我們需要遵循APCS準(zhǔn)則。函數(shù)編譯器將處理為函數(shù)代碼為一段.global的匯編碼。(2)函數(shù)的編寫應(yīng)當(dāng)遵循如下規(guī)則:? a1-a4寄存器(參數(shù)、結(jié)果或暫存寄存器,r0到r3 的同義字)以及浮點(diǎn)寄存器f0-f3(如果存在浮點(diǎn)協(xié)處理器)在函數(shù)中是不必保存的;? 如果函數(shù)返回一個不大于一個字大小的值,則在函數(shù)結(jié)束時(shí)應(yīng)該把這個值送到 r0 中;? 如果函數(shù)返回一個浮點(diǎn)數(shù),則在函數(shù)結(jié)束時(shí)把它放入浮點(diǎn)寄存器f0中;?如果函數(shù)的過程改動了sp(堆棧指針,r13)、fp(框架指針,r11)、sl(堆棧限制,r10)、lr(連接寄存器,r14)、v1-v8(變量寄存器,r4 到 r11)和 f4-f7,那么函數(shù)結(jié)束時(shí)這些寄存器應(yīng)當(dāng)被恢復(fù)為包含在進(jìn)入函數(shù)時(shí)它所持有的值。3. .align .end .include .incbin偽操作(1).align:用來指定數(shù)據(jù)的對齊方式,格式如下: .align absexpr1, absexpr2 以某種對齊方式,在未使用的存儲區(qū)域填充值. 第一個值表示對齊方式,4, 8,16或 32. 第二個表達(dá)式值表示填充的值。(2).end:表明源文件的結(jié)束。(3).include:可以將指定的文件在使用.include 的地方展開,一般是頭文件,例如: .include “myarmasm.h”(4).incbin偽操作可以將原封不動的一個二進(jìn)制文件編譯到當(dāng)前文件中,使用方法如下: .incbin file,skip,count skip表明是從文件開始跳過skip個字節(jié)開始讀取文件,count是讀取的字?jǐn)?shù).4. .if偽操作根據(jù)一個表達(dá)式的值來決定是否要編譯下面的代碼, 用.endif偽操作來表示條件判斷的結(jié)束, 中間可以使用.else來決定.if的條件不滿足的情況下應(yīng)該編譯哪一部分代碼。.if有多個變種: .ifdef symbol 判斷symbol是否定義 .ifc string1,string2 字符串string1和string2是否相等,字符串可以用單引號括起來 .ifeq expression 判斷expression的值是否為0.ifeqs string1,string2 判斷string1和string2是否相等,字符 串必須用雙引號括起來.ifge expression 判斷expression的值是否大于等于0.ifgt absolute expression 判斷expression的值是否大于0.ifle expression 判斷expression的值是否小于等于0.iflt absolute expression 判斷expression的值是否小于0.ifnc string1,string2 判斷string1和string2是否不相等, 其用法跟.ifc恰好相反。.ifndef symbol, .ifnotdef symbol 判斷是否沒有定義symbol, 跟.ifdef恰好相反.ifne expression 如果expression的值不是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, 4a:.long 10【例7】.section .text.type asmfunc, function.globl asmfuncasmfunc:mov pc, lr(3)列表控制語句:.title:用來指定匯編列表的標(biāo)題,例如: .title “my program”.list:用來輸出列表文件.6. ARM特有的偽操作(1) .reg: 用來給寄存器賦予別名,格式如下: 別名 .req 寄存器名(2) .unreq: 用來取消一個寄存器的別名,格式如下:.unreq 寄存器別名注意被取消的別名必須事先定義過,否則編譯器就會報(bào)錯,這個偽操作也可以用來取消系統(tǒng)預(yù)制的別名, 例如r0, 但如果沒有必要的話不推薦那樣做。(3) .code偽操作用來選擇ARM或者Thumb指令集,格式如下:.code 表達(dá)式如果表達(dá)式的值為16則表明下面的指令為Thumb指令,如果表達(dá)式的值為32則表明下面的指令為ARM指令.(4) .thumb偽操作等同于.code 16, 表明使用Thumb指令, 類似的.arm等同于.code 32(5) .force_thumb偽操作用來強(qiáng)制目標(biāo)處理器選擇thumb的指令集而不管處理器是否支持(6) .thumb_func偽操作用來指明一個函數(shù)是thumb指令集的函數(shù)(7) .thumb_set偽操作的作用類似于.set, 可以用來給一個標(biāo)志起一個別名, 比.set功能增加的一點(diǎn)是可以把一個標(biāo)志標(biāo)記為thumb函數(shù)的入口, 這點(diǎn)功能等同于.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ù)隊(duì)列。(與armasm中的DCD功能相同)可以使用.word把標(biāo)識符作為常量使用 例如: Start: valueOfStart: .word Start 這樣程序的開頭Start便被存入了內(nèi)存變量valueOfStart中。(11).hword , 插入一個16-bit的數(shù)據(jù)隊(duì)列。(與armasm中的DCW相同)八. GNU ARM匯編特殊字符和語法代碼行中的注釋符號: 整行注釋符號: #語句分離符號: ;直接操作數(shù)前綴: # 或 $第二部分 GNU的編譯器和調(diào)試工具一. 編譯工具1編輯工具介紹GNU 提供的編譯工具包括匯編器as、C編譯器gcc、C+編譯器g+、連接器ld和二進(jìn)制轉(zhuǎn)換工具objcopy?;贏RM平臺的工具分別為arm- linux-as、arm-linux-gcc、arm-linux-g+、arm-linux-ld和arm-linux- objcopy。GNU的編譯器功能非常強(qiáng)大,共有上百個操作選項(xiàng),這也是這類工具讓初學(xué)者頭痛的原因。不過,實(shí)際開發(fā)中只需要用到有限的幾個,大部分可以采用缺省選項(xiàng)。GNU工具的開發(fā)流程如下:編寫C、C+語言或匯編源程序,用gcc或g+生成目標(biāo)文件,編寫連接腳本文件,用連接器生成最終目標(biāo)文件(elf格式),用二進(jìn)制轉(zhuǎn)換工具生成可下載的二進(jìn)制代碼。(1)編寫C、C+語言或匯編源程序通常匯編源程序用于系統(tǒng)最基本的初始化,如初始化堆棧指針、設(shè)置頁表、操作ARM的協(xié)處理器等。初始化完成后就可以跳轉(zhuǎn)到C代碼執(zhí)行。需要注意的是,GNU的匯編器遵循AT&T的匯編語法,讀者可以從GNU的站點(diǎn)()上下載有關(guān)規(guī)范。匯編程序的缺省入口是 start標(biāo)號,用戶也可以在連接腳本文件中用ENTRY標(biāo)志指明其它入口點(diǎn)(見下文關(guān)于連接腳本的說明)。(2)用gcc或g+生成目標(biāo)文件如果應(yīng)用程序包括多個文件,就需要進(jìn)行分別編譯,最后用連接器連接起來。如筆者的引導(dǎo)程序包括3個文件:init.s(匯編代碼、初始化硬件)xmrecever.c(通信模塊,采用Xmode協(xié)議)和flash.c(Flash擦寫模塊)。分別用如下命令生成目標(biāo)文件: 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命令表示只生成目標(biāo)代碼,不進(jìn)行連接;-o命令指明目標(biāo)文件的名稱;-O2表示采用二級優(yōu)化,采用優(yōu)化后可使生成的代碼更短,運(yùn)行速度更快。如果項(xiàng)目包含很多文件,則需要編寫makefile文件。關(guān)于makefile的內(nèi)容,請感興趣的讀者參考相關(guān)資料。(3)編寫連接腳本文件gcc 等編譯器內(nèi)置有缺省的連接腳本。如果采用缺省腳本,則生成的目標(biāo)代碼需要操作系統(tǒng)才能加載運(yùn)行。為了能在嵌入式系統(tǒng)上直接運(yùn)行,需要編寫自己的連接腳本文件。編寫連接腳本,首先要對目標(biāo)文件的格式有一定了解。GNU編譯器生成的目標(biāo)文件缺省為elf格式。elf文件由若干段(section)組成,如不特殊指明,由C源程序生成的目標(biāo)代碼中包含如下段:.text(正文段)包含程序的指令代碼;.data(數(shù)據(jù)段)包含固定的數(shù)據(jù),如常量、字符串;.bss(未初始化數(shù)據(jù)段)包含未初始化的變量、數(shù)組等。C+源程序生成的目標(biāo)代碼中還包括.fini(析構(gòu)函數(shù)代碼)和. init(構(gòu)造函數(shù)代碼)等。連接器的任務(wù)就是將多個目標(biāo)文件的.text、.data和.bss等段連接在一起,而連接腳本文件是告訴連接器從什么地址開始放置這些段。例如連接文件link.lds為:ENTRY(begin)SECTION.=0x30000000;.text:*(.text).data:*(.data).bss:*(.bss)其中,ENTRY(begin)指明程序的入口點(diǎn)為begin標(biāo)號;.=0x00300000指明目標(biāo)代碼的起始地址為0x30000000,這一段地址為 MX1的片內(nèi)RAM;.text:*(.text)表示從0x30000000開始放置所有目標(biāo)文件的代碼段,隨后的.data:* (.data)表示數(shù)據(jù)段從代碼段的末尾開始,再后是.bss段。(4)用連接器生成最終目標(biāo)文件有了連接腳本文件,如下命令可生成最終的目標(biāo)文件:arm-linux-ld no stadlib o bootstrap.elf -Tlink.lds init.o xmrecever.o flash.o其中,ostadlib表示不連接系統(tǒng)的運(yùn)行庫,而是直接從begin入口;-o指明目標(biāo)文件的名稱;-T指明采用的連接腳本文件(也可以使用-Ttext address,address表示執(zhí)行區(qū)地址);最后是需要連接的目標(biāo)文件列表。(5)生成二進(jìn)制代碼連接生成的elf文件還不能直接下載執(zhí)行,通過objcopy工具可生成最終的二進(jìn)制文件:arm-linux-objcopy O binary bootstrap.elf bootstrap.bin其中-O binary指定生成為二進(jìn)制格式文件。Objcopy還可以生成S格式的文件,只需將參數(shù)換成-O srec。還可以使用-S選項(xiàng),移除所有的符號信息及重定位信息。如果想將生成的目標(biāo)代碼反匯編,還可以用objdump工具: arm-linux-objdump -D bootstrap.elf至此,所生成的目標(biāo)文件就可以直接寫入Flash中運(yùn)行了。2Makefile實(shí)例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二. 調(diào)試工具Linux 下的GNU調(diào)試工具主要是gdb、gdbserver和kgdb。其中g(shù)db和gdbserver可完成對目標(biāo)板上Linux下應(yīng)用程序的遠(yuǎn)程調(diào)試。 gdbserver是一個很小的應(yīng)用程序,運(yùn)行于目標(biāo)板上,可監(jiān)控被調(diào)試進(jìn)程的運(yùn)行,并通過串口與上位機(jī)上的gdb通信。開發(fā)者可以通過上位機(jī)的gdb輸入命令,控制目標(biāo)板上進(jìn)程的運(yùn)行,查看內(nèi)存和寄存器的內(nèi)容。gdb5.1.1以后的版本加入了對ARM處理器的支持,在初始化時(shí)加入 target=arm參數(shù)可直接生成基于ARM平臺的gdbserver。gdb工具可以從ftp: //pub/gnu/gdb/上下載。對于Linux內(nèi)核的調(diào)試,可以采用kgdb工具,同樣需要通過串口與上位機(jī)上的gdb通信,對目標(biāo)板的Linux內(nèi)核進(jìn)行調(diào)試??梢詮?projects/kgdb/上了解具體的使用方法。參考資料:1. Richard Blum,Professional Assembly Language2. GNU ARM 匯編快速入門,/u/31996/showart.php?id=3261463. ARM GNU 匯編偽指令簡介,/jb8164/archive/2008/01/22/41661.aspx4. GNU匯編使用經(jīng)驗(yàn),/u1/37614/showart_390095.html5. GNU的編譯器和開發(fā)工具,/blog-htm-do-showone-uid-34335-itemid-81387-type-blog.html6. 用GNU工具開發(fā)基于ARM的嵌入式系統(tǒng),/liren0126/blog/static/32897598200821211144696/7. objcopy命令介紹,/junhua198310/archive/2007/06/27/1669545.aspxARM GNU 匯編偽指令簡介1 ARM GNU 匯編偽指令簡介 (1)abort .abort 停止匯編 (2)align .align absexpr1,absexpr2 以某種對齊方式,在未使用的存儲區(qū)域填充值. 第一個值表示對齊方式,4, 8,16或 32. 第二個表達(dá)式值表示填充的值 (3)if.else.endif .if .else .endif: 支持條件預(yù)編譯 (4)include .include file: 包含指定的頭文件, 可以把一個匯編常量定義放在頭文件中 (5)comm .comm symbol, length: 在bss段申請一段命名空間,該段空間的名稱叫symbol, 長度為length. Ld連接器在連接 會為它留出空間 (6)data .data subsection: 說明接下來的定義歸屬于subsection數(shù)據(jù)段 (7)equ .equ symbol, expression: 把某一個符號(symbol)定義成某一個值(expression).該 指令并不分配空間 (8)global .global symbol: 定義一個全局符號, 通常是為ld使用 (9)ascii .ascii string: 定義一個字符串并為之分配空間 (10)byte .byte expressions: 定義一個字節(jié), 并為之分配空間 (11)short .short expressions: 定義一個短整型, 并為之分配空間 (12)int .int expressions: 定義一個整型,并為之分配空間 (13)long .long expressions: 定義一個長整型, 并為之分配空間 (14)word .word expressions: 定義一個字,并為之分配空間, 4 bytes (15)macro/endm .macro: 定義一段宏代碼, .macro表示代碼的開始, .endm表示代碼的結(jié)束, .exitm 跳出宏, 示例如下: .macro SHIFTLEFT a, b .if b 0 mov a, a, ASR #-b .exitm .endif mov a, a, LSL #b .endm (16)req name .req register name: 為寄存器定義一個別名 (17)code .code 16|32: 指定指令代碼產(chǎn)生的長度, 16表示Thumb指令, 32表示ARM指令 (18)ltorg .ltorg: 表示當(dāng)前往下的定義在歸于當(dāng)前段,并為之分配空間2 ARM GNU專有符號 (1) 表示注釋從當(dāng)前位置到行尾的字符. (2)# 注釋掉一整行. (3); 新行分隔符.3 操作碼 (1)NOP: nop 空操作, 相當(dāng)于MOV r0, r0 (2)LDR: ldr , = 相當(dāng)于PC寄存器或其它寄存器的長轉(zhuǎn)移 (3)ADR: adr 相于PC寄存器或其它寄存器的小范圍轉(zhuǎn)移 (4)ADRL: adrl 相于PC寄存器或其寄存器的中范圍轉(zhuǎn)移GNU的編譯器和開發(fā)工具已有 616 次閱讀 2006-8-24 18:30 |系統(tǒng)分類:其他 文字文字 GNU提供的編譯工具包括匯編器as、C編譯器gcc、C+編譯器g+、連接器ld和二進(jìn)制轉(zhuǎn)換工具objcopy?;贏RM平臺的工具分別為 arm-linux-as、arm-linux-gcc、arm-linux-g+、arm -linux-ld 和arm-linux-objcopy。GNU的所有開發(fā)工具都可以從上下載,基于ARM的工具可以從獲 得。GNU的編譯器功能非常強(qiáng)大,共有上百個操作選項(xiàng),這也是這類工具讓初學(xué)者頭痛的原因。不過,實(shí)際開發(fā)中只需要用到有限的幾個,大部分可以采用缺省選 項(xiàng)。GNU工具的開發(fā)流程如下:編寫C、C+語言或匯編源程序,用gcc或g+生成目標(biāo)文件,編寫連接腳本文件,用連接器生成最終目標(biāo)文件(elf格 式),用二進(jìn)制轉(zhuǎn)換工具生成可下載的二進(jìn)制代碼。GNU工具都運(yùn)行在Linux下,開發(fā)者需要1臺運(yùn)行Linux的PC作為上位機(jī)。由于篇幅所限,不能完 整地介紹整個嵌入式操作系統(tǒng)的開發(fā)過程,將以第二節(jié)中提到的通過自舉模式下載的引導(dǎo)程序?yàn)槔f明開發(fā)的過程。對于像Linux這樣的大系統(tǒng),基本的開發(fā) 流程是一樣的。 引導(dǎo)程序?qū)⑼ㄟ^自舉模式下載到MX1的片內(nèi)RAM,從地址0x00300000開始并執(zhí)行。完成串口和SDRAM的初始化后,引導(dǎo)程序?qū)⒌却邮諔?yīng)用 程序或操作系統(tǒng)內(nèi)核,將接收到的數(shù)據(jù)放在SDRAM中。數(shù)據(jù)接收完畢后,引導(dǎo)程序?qū)DRAM中的數(shù)據(jù)寫入Flash,下一次就可以從Flash中直接引 導(dǎo)系統(tǒng)了。由于操作系統(tǒng)的內(nèi)核比較大,如Linux有1 MB以上,下載過程必須考慮糾錯。因此,接收部分采用Xmode協(xié)議,可以用Windows下超級終端的Xmode發(fā)送方式發(fā)送文件。(1)編寫C、C+語言或匯編源程序通常匯編源程序用于系統(tǒng)最基本的初始化,如初始化堆棧指針、設(shè)置頁表、操作ARM的協(xié)處理器等。初始化完成后就可以跳轉(zhuǎn)到C代碼執(zhí)行。需要注意的是,GNU的匯編器遵循AT&T的匯編語法,讀者可以從GNU的站點(diǎn)()上下載有關(guān)規(guī)范。匯編程序的缺省入口是start標(biāo)號,用戶也可以在連接腳本文件中用ENTRY標(biāo)志指明其它入口點(diǎn)(見下文關(guān)于連接腳本的說明)。(2)用gcc或g+生成目標(biāo)文件如果應(yīng)用程序包括多個文件,就需要進(jìn)行分別編譯,最后用連接器連接起來。如筆者的引導(dǎo)程序包括3個文件:init.s(匯編代碼、初始化硬件) xmrecever.c(通信模塊,采用Xmode協(xié)議)和flash.c(Flash擦寫模塊)。分別用如下命令生成目標(biāo)文件:arm-linux-gcc-c-O2-o init.o init.sarm-linux-gcc-c-O2-o xmrecever.o xmrecever.carm-linux-gcc-c-O2-o flash.o flash.c其中-c命令表示只生成目標(biāo)代碼,不進(jìn)行連接;-o 命令指明目標(biāo)文件的名稱;-O2表示采用二級優(yōu)化,采用優(yōu)化后可使生成的代碼更短,運(yùn)行速度更快。如果項(xiàng)目包含很多文件,則需要編寫makefile文件。關(guān)于makefile的內(nèi)容,請感興趣的讀者參考相關(guān)資料。(3)編寫連接腳本文件gcc等編譯器內(nèi)置有缺省的連接腳本。如果采用缺省腳本,則生成的目標(biāo)代碼需要操作系統(tǒng)才能加載運(yùn)行。為了能在嵌入式系統(tǒng)上直接運(yùn)行,需要編寫自己的 連接腳本文件。編寫連接腳本,首先要對目標(biāo)文件的格式有一定了解。GNU編譯器生成的目標(biāo)文件缺省為elf格式。elf文件由若干段(section)組 成,如不特殊指明,由C源程序生成的目標(biāo)代碼中包含如下段:.text(正文段)包含程序的指令代碼;.data(數(shù)據(jù)段)包含固定的數(shù)據(jù),如常量、字符 串;.bss(未初始化數(shù)據(jù)段)包含未初始化的變量、數(shù)組等。C+源程序生成的目標(biāo)代碼中還包括.fini(析構(gòu)函數(shù)代碼)和.init(構(gòu)造函數(shù)代 碼)等。有關(guān)elf文件格式,讀者可自行參考相關(guān)資料。連接器的任務(wù)就是將多個目標(biāo)文件的.text、.data和.bss等段連接在一起,而連接腳本文 件是告訴連接器從什么地址開始放置這些段。例如筆者的引導(dǎo)程序連接文件link.lds為:ENTRY(begin)SECTION .=0x00300000;.text : *(.text) .data: *(.data) .bss: *(.bss) 其中,ENTRY(begin)指明程序的入口點(diǎn)為begin標(biāo)號;.=0x00300000指明目標(biāo)代碼的起始地址為0x00300000,這一段 地址為MX1的片內(nèi)RAM;.text : *(.text) 表示從0x00300000開始放置所有目標(biāo)文件的代碼段,隨后的.data: *(.data) 表示數(shù)據(jù)段從代碼段的末尾開始,再后是.bss段。(4)用連接器生成最終目標(biāo)文件有了連接腳本文件,如下命令可生成最終的目標(biāo)文件:arm-linux-ld-nostadlib-o bootstrap.elf-T link.lds init.o xmrecever.o flash.o其中,ostadlib表示不連接系統(tǒng)的運(yùn)行庫,而是直接從begin入口;-o指明目標(biāo)文件的名稱;-T指明采用的連接腳本文件;最后是需要連接的目標(biāo)文件列表。(5)生成二進(jìn)制代碼連接生成的elf文件還不能直接下載執(zhí)行,通過objcopy工具可生成最終的二進(jìn)制文件:arm-linux-objcopy-O binary bootstrap.elf bootstrap.bin其中-Obinary指定生成為二進(jìn)制格式文件。Objcopy還可以生成S格式的文件,只需將參數(shù)換成-O srec。如果想將生成的目標(biāo)代碼反匯編,還可以用objdump工具:arm-linux-objdump-D bootstrap.elf至此,所生成的目標(biāo)文件就可以直接寫入Flash中運(yùn)行了。如果要通過自舉模式下載,還需要轉(zhuǎn)換為自舉模式的文件格式,相關(guān)轉(zhuǎn)換工具可以在摩托羅拉的網(wǎng)站上找到。掌握了GNU工具后,開發(fā)者就可以開發(fā)或移植C或C+代碼的程序。用戶可以不需要操作系統(tǒng),直接開發(fā)簡單應(yīng)用程序。但對于更復(fù)雜的應(yīng)用來說,操作系 統(tǒng)必不可少。目前流行的源代碼公開的操作系統(tǒng)如Linux、C/OS都可以用GNU工具編譯。ARM的Linux已有很多成熟的版本,可以支持 ARM720、ARM920、ARM1020等多種處理器,讀者可從或上 獲取最新信息。Linux移植過程中和處理器相關(guān)的代碼都放在arch/arm目錄下。對于內(nèi)核,用戶需要做的是設(shè)定自己系統(tǒng)的內(nèi)存映像,RAM起始地 址,I/O地址空間和虛擬I/O地址空間,參看arch/arm/mach-integrator/arch.c文件。除了內(nèi)核外,用戶還需要為自己的系 統(tǒng)編制各種各樣的驅(qū)動程序GNU ARM匯編語言GNU ARM 匯編快速入門任何匯編行都是如下結(jié)構(gòu): : comment: 注釋 GNU ARM 匯編中,任何以冒號結(jié)尾的都被認(rèn)為是一個標(biāo)簽,而不一定非要在一行的開始。下面是一個簡單的例子,這段匯編程序定義了一個add的函數(shù),該函數(shù)返回兩個參數(shù)的和:.section .text, “x”.global add give the symbol add external linkageadd:ADD r0, r0, r1 add input argumentsMOV pc, lr return from subroutine end of programGNU ARM匯編偽指令下面列出了一些GNU ARM匯編偽指令,并給出了相應(yīng)說明。.ascii “” 在匯編中定義字符串并為之分配存儲空間(與armasm中的DCB功能類似)。.asciz “” 和.ascii類似, 但不分配存儲空間。 .balign , , 以某種排列方式在內(nèi)存中填充數(shù)值。 (該指令與armasm

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論