GNU-ARM汇编._第1页
GNU-ARM汇编._第2页
免费预览已结束,剩余9页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、GNU ARM汇编指令(2008-10-29 00:16:10)标签:linuxgnu arm汇编指分类:技术文摘令it第一部分 Linux 下 ARM 匚编语法尽管在 Linux 下使用 C 或 C+编写程序很方便,但汇编源程 序用于系统最基本的初始化,如初始化堆栈指针、设置页表、操作ARM 的协处理器等。初始化完成后就可以跳转到C 代码执行。需要注意的是,GNU 的汇编器遵循 AT&T 的汇编语法,可以从 GNU 的站点( )上下载有关规范。一.Li nux 汇编行结构任何汇编行都是如下结构:: comme nt: 注释Linux ARM 汇编中, 任何以冒号

2、结尾的标识符都被认为是一个标号, 开始。【例 1】定义一个add的函数,返回两个参数的和。.secti on .text,“ x”.global add give the symbol add exter nal li nkageadd:ADD rO, rO, r1 add in put argume ntsMOV pc, lr retur n from subrouti ne end of program而不一定非要在一行的二.Li nux汇编程序中的标号标号只能由 az, AZ 09, “. ”,等字符组成。当标号为09 的数字时为局部标号,局部标号可以重复出现,使用方法如下:标号 f:在

3、引用的地方向前的标号标号 b:在引用的地方向后的标号【例 2】使用局部符号的例子,一段循环程序1:subs r0,r0,#1 每次循环使 r0=r0-1bne 1f 跳转到 1 标号去执行局部标号代表它所在的地址,因此也可以当作变量或者函数来使用。三.Li nux汇编程序中的分段(1) .section 伪操作用户可以通过.section 伪操作来自定义一个段,格式如下:.sect ion secti on_n ame , flags, %type,flag_specific_arguments每一个段以段名为开始 , 以下一个段名或者文件结尾为结束。这些段都有缺省的标志(gs),连接器可以识

4、别这些标志。(与 armasm 中的 AREA 相同)。下面是 ELF 格式允许的段标志 含义a 允许段w 可写段x 执行段【例 3】定义段.section .mysection 自定义数据段,段名为“ .mysection ”.align 2strtemp:.ascii Temp string n0(2)汇编系统预定义的段名.text 代码段.data 初始化数据段.bss 未初始化数据段.sdata .sbss 需要注意的是,源程序中 .bss 段应该在 .text 之前。四. 定义入口点汇编程序的缺省入口是 start 标号,用户也可以在连接脚本文件中用 入口点。【例 4】定义入口点.s

5、ection.data.section .bss.section .text.globl _start_start:五. Linux 汇编程序中的宏定义 格式如下 :.macro 宏名 参数名列表 伪指令 .macro 定义一个宏flaENTRY 标志指明其它宏体.endm .endm 表示宏结束如果宏使用参数 , 那么在宏体中使用该参数时添加前缀 “ ”。宏定义时的参数还可以使用默 认值。可以使用 .exitm 伪指令来退出宏。【例 5】宏定义.macro SHIFTLEFT a, b.if b 0MOV a, a, ASR #-b.exitm.endifMOV a, a, LSL #b.e

6、ndm六 . Linux 汇编程序中的常数(1)十进制数以非 0 数字开头 , 如:123 和 9876;(2) 二进制数以 Ob 开头,其中字母也可以为大写;(3) 八进制数以 0 开始 , 如:0456,0123 ;(4) 十六进制数以 Ox 开头,如:0 xabcd,0X123f ;( 5 )字符串常量需要用引号括起来,中间也可以使用转义字符,如: “You are welcome!n ”;(6)当前地址以“ .”表示 , 在汇编程序中可以使用这个符号代表当前指令的地址;( 7)表达式 : 在汇编程序中的表达式可以使用常数或者数值 , “ - ”表示取负数 , “”表示 取补,“”表示不

7、相等,其他的符号如:+:+、- -、* *、/ /、 、| |、& &、人人、!、=、 =、=、& |跟 C 语言中的用法相似。七 Linux 下 ARM 匚编的常用伪操作在前面已经提到过了一些为操作,还有下面一些为操作:数据定义伪操作: .byte , .short , .long , .quad , .float , .string/.asciz/.ascii,重复定义伪操作 .rept ,赋值语句 .equ/.set ;函数的定义 ;对齐方式伪操作 .align ;源文件结束伪操作 .end ;.include 伪操作;if 伪操作;.global/ .globl

8、 伪操作 ;.type 伪操作 ;列表控制语句 ;区别于 gas 汇编的通用伪操作,下面是 ARM 寺有的伪操作:.reg , .unreq , .code , .thumb , .thumb_func , .thumb_set , .ltorg , .pool1. 数据定义伪操作(1) .byte: 单字节定义,如: .byte 1,2,0b01,0 x34,072,s;(2) .short:定义双字节数据,如 :.short 0 x1234,60000;(3) .long: 定义 4 字节数据,如 :.long 0 x12345678,23876565(4) .quad: 定义 8 字节,

9、如 :.quad 0 x1234567890abcd(5) .float:定义浮点数,如 :.float 0f-31415926535897932384626433832795028841971.693993751E-40 - pi(6) .string/.asciz/.ascii:定义多个字符串,如 :.string abcd, efgh, hello!.asciz qwer, sun, world!.ascii welcome0需要注意的是: .ascii 伪操作定义的字符串需要自行添加结尾字符 0 。(7) .rept:重复定义伪操作 , 格式如下 :.rept 重复次数数据定义.end

10、r 结束重复定义例如 :.rept 3.byte 0 x23.endr(8) .equ/.set:赋值语句 , 格式如下 :.equ(.set) 变量名 , 表达式例如 :.equ abc 3 让 abc=32. 函数的定义伪操作(1)函数的定义 , 格式如下 :函数名 :函数体返回语句一般的 , 函数如果需要在其他文件中调用 , 需要用到 .global 伪操作将函数声明为全局函数。为了不至于在其他程序在调用某个C 函数时发生混乱,对寄存器的使用我们需要遵循APCS 准则。函数编译器将处理为函数代码为一段.global 的汇编码。(2 )函数的编写应当遵循如下规则:a1-a4 寄存器(参数、

11、结果或暂存寄存器,r0 到 r3 的同义字)以及浮点寄存器 f0-f3(如 果存在浮点协处理器)在函数中是不必保存的;如果函数返回一个不大于一个字大小的值,则在函数结束时应该把这个值送到r0 中;如果函数返回一个浮点数,则在函数结束时把它放入浮点寄存器f0 中;卅址*兹鬥辽柑彥胡sp (堆栈指针,r13 )、fp (框架指针,r11 )、si (堆栈限制,r10)、lr (连接寄存器,r14 )、v1-v8 (变量寄存器,r4 到 r11 )和 f4-f7,那么函数结束 时这些寄存器应当被恢复为包含在进入函数时它所持有的值。3. .alig n .end .in elude .incbin伪操

12、作(1) .align:用来指定数据的对齐方式,格式如下:.alig n absexprl, absexpr2以某种对齐方式,在未使用的存储区域填充值.第一个值表示对齐方式,4, 8,16 或 32. 第二个表达式值表示填充的值。(2).end:表明源文件的结束。(3) .include:可以将指定的文件在使用.inelude 的地方展开,一般是头文件,例如:.in elude“ myarmasm.h”(4) .inebin 伪操作可以将原封不动的一个二进制文件编译到当前文件中,使用方法如下.in ebin file,skip,cou ntskip 表明是从文件开始跳过skip 个字节开始读取

13、文件,eount 是读取的字数.4. .if 伪操作根据一个表达式的值来决定是否要编译下面的代码,用.endif 伪操作来表示条件判断的结束,中间可以使用.else 来决定.if 的条件不满足的情况下应该编译哪一部分代码。 .if 有多个变种:.ifdef symbol 判断 symbol 是否定义字符串 string1 和 string2是否相等,字符串可以用单引号括起判断 expression_r的值是否为 0判断 string1 和 string2 是否相等,字符 串必须用双引号括起来.ifge expression_r 判断 expression_r的值是否大于等于0.ifgt abs

14、olute expression_r 判断 expression_r的值是否大于 0.ifle expression_r 判断 expression_r的值是否小于等于0.iflt absolute expression_r 判断 expression_r的值是否小于 0.ife stri ng1,stri ng2 来.ifeq expressi on_r .ifeqs string1,string2.ifne string1,string2 判断 string1 和 string2 是否不相等,其用法跟.ife 恰好相反。判断是否没有定义symbol,跟.ifdef恰好相反.ifne exp

15、ression_r 如果 expression_r 的值不是 0, 那么编译器将编译下面的代码.ifnes string1,string2 如果字符串 string1 和 string2 不相 等 , 那么编译器将编译下 面的代码 .5. .global .type .title .list(1) .global/ .globl:用来定义一个全局的符号,格式如下 :.global symbol 或者 .globl symbol(2).type :用来指定一个符号的类型是函数类型或者是对象类型, 对象类型一般是数据格式如下 :.type 符号 , 类型描述【例 6】.globl a.data.a

16、lign 4.type a, object.size a, 4a:.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: 用来取消一个寄存器的别名 , 格式如下 :.ifndef symbol, .ifnot

17、def symbol .unreq 寄存器别名注意被取消的别名必须事先定义过 ,否则编译器就会报错 , 这个伪操作也可以用来取消 系统预制的别名 , 例如 r0, 但如果没有必要的话不推荐那样做。(3) .code 伪操作用来选择 ARM 或者 Thumb 指令集,格式如下:.code 表达式如果表达式的值为 16 则表明下面的指令为 Thumb 指令,如果表达式的值为 32 则表明下 面的指令为 ARM 指令.(4).thumb 伪操作等同于.code 16, 表明使用 Thumb 指令,类似的.arm 等同于.code 32(5).force_thumb 伪操作用来强制目标处理器选择 th

18、umb 的指令集而不管处理器是否支 持(6).thumb_func 伪操作用来指明一个函数是 thumb 指令集的函数(7).thumb_set 伪操作的作用类似于.set, 可以用来给一个标志起一个别名,比.set 功 能增加的一点是可以把一个标志标记为 thumb 函数的入口 , 这点功能等同于 .thumb_func(8).ltorg 用于声明一个数据缓冲池 (literal pool) 的开始,它可以分配很大的空间。(9).pool 的作用等同 .ltorg( 9) .space ,分配 number_of_bytes 字节的数据空间,并填充其值为 fill_byte ,若未指定该值,

19、缺省填 充 0。(与armasm 中的 SPACE 功能相同)(10) .word ,插入一个 32-bit 的数据队列。(与 armasm 中的 DCD 功能相同) 可以使用 .word 把标识符作为常量使用例如:Start:valueOfStart:.word Start这样程序的开头 Start 便被存入了内存变量 valueOfStart 中。(11 ).hword ,插入一个 16-bit 的数据队列。(与 armasm 中的 DCW 相同)八. GNU ARM 汇编特殊字符和语法 代码行中的注释符号: 整行注释符号: # 语句分离符号: ; 直接操作数前缀:# 或 $第二部分 GN

20、U 的编译器和调试工具一. 编译工具1 编辑工具介绍GNU 提供的编译工具包括汇编器as、C 编译器 gcc、C+编译器 g+、连接器 Id 和二进制转换工具 objcopy。基于 ARM 平台的工具分另 U 为 arm- linux-as 、arm-linux-gcc 、arm-linux-g+、arm-linux-ld和 arm-linux- objcopy。GNU 的编译器功能非常强大,共有上百个操作选项,这也是这类工具让初学者头痛的原因。不过,实际开发中只需要用到有限的几个, 大部分可以采用缺省选项。GNU 工具的开发流程如下:编写C、C+语言或汇编源程序,用gcc 或 g+生成目标文

21、件,编写连接脚本文件,用连接器生成最终目标文件(elf 格式),用二进制转换工具生成可下载的二进制代码。(1)编写 C C+语言或汇编源程序通常汇编源程序用于系统最基本的初始化,如初始化堆栈指针、设置页表、操作 ARM 的协处理器等。初始化完成后就可以跳转到C 代码执行。需要注意的是,GNU 勺汇编器遵循 AT&T的汇编语法,读者可以从GNU 的站点( )上下载有关规范。汇编程序的缺省入口是 start 标号,用户也可以在连接脚本文件中用ENTR 柝志指明其它入口点(见下文关于连接脚本的说明)。(2 )用 gcc 或 g+生成目标文件如果应用程序包括多个文件, 就

22、需要进行分另编译, 最后用连接器连接起来。 如笔者的引导 程序包括 3 个文件: init.s(汇编代码、初始化硬件) xmrecever.c(通信模块,采用 Xmod e 协议)和 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 命令指明目标文件的名称;-02 表示采用二级优化,采用优化后可使生成的

23、代码更短,运行速度更快。如果项目包含很多文件,则需要编写makefile文件。关于 makefile 的内容,请感兴趣的读者参考相关资料。( 3)编写连接脚本文件gcc 等编译器内置有缺省的连接脚本。 如果采用缺省脚本, 则生成的目标代码需要操作系统 才能加载运行。 为了能在嵌入式系统上直接运行, 需要编写自己的连接脚本文件。 编写连接 脚本,首先要对目标文件的格式有一定了解。GNU 编译器生成的目标文件缺省为elf 格式。elf 文件由若干段(section )组成,如不特殊指明,由C 源程序生成的目标代码中包含如下段:.text(正文段)包含程序的指令代码;.data( 数据段 )包含固定

24、的数据,如常量、字 符串;.bss(未初始化数据段)包含未初始化的变量、数组等。C+源程序生成的目标代码中还包括 .fini (析构函数代码)和 . init (构造函数代码)等。连接器的任务就是将多个 目标文件的.text、.data 和.bss 等段连接在一起,而连接脚本文件是告诉连接器从什么地 址开始放置这些段。例如连接文件 link.lds 为:ENTRY(begin)SECTI0N.=0 x30000000;.text:*(.text).data:*(.data).bss:*(.bss)其中,ENTRY(begin)指明程序的入口点为begin 标号;.=0 x00300000 指明

25、目标代码的起始地址为 0 x30000000,这一段地址为 MX1 的片内 RAM .text:*(.text) 表示从 0 x30000000 开始放置所有目标文件的代码段,随后的 .data:* (.data) 表示数据段从代码段的末尾开 始,再后是 .bss 段。(4)用连接器生成最终目标文件 有了连接脚本文件,如下命令可生成最终的目标文件:arm-li nu x-ld no stadlib o bootstrap.elf -Tli nk.lds in it.o xmrecever.o flash.o其中,ostadlib 表示不连接系统的运行库,而是直接从begin 入口; -o 指明

26、目标文件的名称; -T 指明采用的连接脚本文件 (也可以使用 -Ttext address , address 表示执行区地址) ; 最后是需要连接的目标文件列表。(5)生成二进制代码连接生成的 elf 文件还不能直接下载执行,通过 objcopy 工具可生成最终的二进制文件:arm-linux-objcopy- O binary bootstrap.elf bootstrap.bin其中-O bin ary 指定生成为二进制格式文件。Objcopy 还可以生成 S 格式的文件,只需将参数换成 -O srec 。还可以使用 -S 选项,移除所有的符号信息及重定位信息。如果想将生成的 目标代码反汇编,还可以用 objdump 工具:arm-linux-objdump -D bootstrap.elf至此,所生成的目标文件就可以直接写入

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论