GNU汇编语法.doc_第1页
GNU汇编语法.doc_第2页
GNU汇编语法.doc_第3页
GNU汇编语法.doc_第4页
GNU汇编语法.doc_第5页
已阅读5页,还剩10页未读 继续免费阅读

下载本文档

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

文档简介

GNU汇编语法Version:1.02008-5-29姜小科GNU汇编器是GNU工具套件之一,其作用是把ARM汇编源代码转换成二进制对象文件。该汇编器的详细资料请参见GNUAssemblerManual,本文是该手册的摘要。例子和模板文件Examples文件夹和他的子文件夹包含很多汇编语言程序例子,你可以学习它们。Examples有一个子文件是templates。在你开始写程序之前,强烈建议你使用那个文件夹提供的模板做为起点。特别的,template.s文件应该在你所有的ARM程序中使用。在去除大部分该文件的注释后,内容如下:.text;以下为可执行代码_start:.global_start;_start是连接器所必须的.globalmain;main是主程序bmain;跳转到主程序main:;main程序入口;这里添加你自己的程序movpc,lr;返回.end调用汇编器你可以使用arm-elf-as工具来编译任何ARM汇编代码,该工具的调用方式如下:arm-elf-as-marm7tdmi-gdwarf2-ofilename.ofilename.s其中:Filename需要编译的文件。-marm7tdmi告诉GNU汇编器你的CPU内型是ARM7TDMI(ARMv4T版本)。-gdwarf2让汇编器附带输出DEBUG信息GNUAssemblerReference的第一章,第二章以及8.4节列出了其他选项。对于大的工程来说,必须按模块划分成多个源文件。每个源文件(后缀为.s)的编译方法和上面所示的单个文件的方法一样。当你已经把源文件编译成二进制目标文件(后缀名.o)后,可以使用GNU链接器生成最终的可执行文件(后缀.elf),调用方式如下:arm-elf-ld-ofilename.elffilename.o一次又一次的输入命令行将十分枯燥(尽管UnixShell允许你使用方向键的向上键来显示上一次的命令),为了解决上述问题,你可以修改GNU提供的Makefile模板来达到你自己的目的(该模板的路径为:examples/templates/Makefile.template-asm)。一旦修改完该文件(并且重新命名该文件:Makefile),接下来所要做的就是输入命令:Make汇编语言语法GNU汇编器支持多种架构的CPU而不仅仅是ARM。正因为如此,它的汇编语法和其他的ARM汇编器有细微的区别。GNU汇编器对于其支持的45种CPU架构采用相同的汇编语法。汇编源文件由声明(每行一个)组成,声明格式如下,声明的每个部分都是可选的。label:instruction;commentlabel可以确定其所在位置的程序计数器(pc)值,然后你就可以使用它。例子:在分支或者load和store指令中的目标。一个标号可以由任何有效的字符和冒号组成,所谓有效的字符包含以下字符:字母A-Z,a-z,数字0-9,符号_,.,$。但是要注意的是标号不能以数字开头(更多信息请看GNUAssemblerReference的3.4和5.3节)。Comment以;开头,不管是什么内容。除了在字符串中出现的分号,系统将忽律整行。C语言风格的注释(/*/)也同样被支持,同样的你也可以使用来代替分号;。Instruction区域是你的程序的主要组成:你可以使用任何你想用的ARM汇编语言指令。同样包括所谓的伪指令或者汇编命令(用来告诉汇编器自己干某些特殊的事)。这些汇编命令将在下面做详细介绍。汇编命令所有的汇编命令都是以.开头。这些命令在GNUAssemblerReference的第七章做了更加详细的介绍。下面所列出的这些命令(按字母排列)是在程序中最常用的。.align插入0到3个字节的0x00,这样下一个位置将是4字节的整数倍。特别的,ARM微控制器总是按字(4字节)读取数据。下面的例子中,输出对象文件中将被插入8字节的内容,假设第一行代码的位置是4字节的整数倍。.byte0x55;插入1个字节0x55.align;顺次插入3个字节:0x000x000x00.word0xAA55EE11;插入内容0x110xEE0x550xAA(小端模式)顺便说一下,前缀0x表示这个数是个16进制数,这个文档后面的表达式部分将对此做详细介绍。这个汇编命令还可以带选项,不过这儿不做介绍。如果你想使用它们,建议你用.balign命令代替。更多信息请看GNUAssemblerReference的7.3。.asciistring在对象文件中按照指定的方法插入数字字符串,该字符串末尾没有NUL字符。该命令一次可以插入多个字符串,字符串之间用,分隔。下面的例子在对象文件中插入3个字节长的字符串。.asciiJNZ;插入3个字节:0x4A0x4E0x5A.ascizstring和.ascii相似,只是生成的字符串以NUL(0x00)结尾。下面的例子在对象文件中插入4个字节长的字符串。.asciiJNZ;插入4个字节:0x4A0x4E0x5A0x00.byteexpression 在对象文件中插入一个字节,内容为expression的值。可以一次插入多个表达式,以,分隔。下面的例子中共向对象文件中插入了5个字节内容。.byte64,A;插入2字节0x400x41.byte0x42;插入字节0x42.byte0b1000011,0104;插入2字节0x430x44注意以0x和0X开头的数字表示该数字是十六进制,以0b和0B开头的数字表示该数字是二进制,以0开头的数字表示该数字是八进制。这个文档后面的表达式部分将对此做详细介绍,同时请看.hword和.word汇编命令部分。.data选择该命令以下的内容位于最终可执行文件的数据段。所有的可执行程序至少包含两个段,.我们称之为.text和.data段。(缺一段)技术上来讲,意味着只有可执行的代码才能出现在.text段(尽管只读恒量也同样适合),可读写的数据才能出现在.data段,不过对于GNU汇编器来说,这并不是强制的。GNUAssemblerReference的第四章将深入讨论这个主题。.end标记一个源代码文件的结尾。所有的在这个命令之后的内容将被汇编器忽略。这个命令完全可选,但强烈建议使用。.equsymbol,expression设置symbol的值为expression。这个汇编指令和.set,=完全一样。下面的例子admas的值都是42:.equadams,(5*8)+2.setadams,0x2Aadams=0b00101010.externsymbol声明symbol的定义在其他源文件中。这个命令是可选的,因为汇编器对于任何未定义的标号都默认为是外部定义的。不过仍然建议使用。.globalsymbol声明symbol是全局可见的。标号_start是GNU链接器用来指定第一个要执行指令所必须的,同样的是全局可见的(并且只能出现在一个模块中)。.hwordexpression.2byteexpression在对象文件中插入半字(16位),内容为expression的值。可以同时插入多个,以,分隔。这个两个命令是一样的。下面的例子在对象文件中插入8个字节内容。.hword0xAA55,12345;插入4字节:0x550xAA0x390x30.2byte0x55AA,-1;插入4字节0xAA0x550xFF0xFF;假设小端模式注意ARM微控制器在16位地址边界上,一次总是读取16位数据,换句话说,它不能一次读取16位数据在一个奇数地址上。请参考.align命令寻找解决办法。同时参考.byte和.word命令。.includefilename在当前源文件中插入filename的内容。这和C语言的#include是同样的效果,所以通过这个命令也可以包含定义变量的头文件。顺便提一下,注意被包含文件中是否有.end:汇编器将忽略后面的所有的内容。.ltorg插入存储恒量的文字池。文字池是ARM汇编语言的伪指令ldr=和adrl所使用。这个汇编指令用的很少,因为GNU汇编器会精确的计算出什么时候,什么地方放置文字池。尽管如此,有些场合该命令仍十分有用,比如说你想在一个特定地址放置你的代码。.setsymbol,expression这个命令和.equ一样,选择哪个是个人的偏好,不过建议使用一致的命令。.skipexpression在目标输出文件中跳过expression个字节。被跳过的字节的值是不可预计的,尽管它们一般被初始化为0。这个命令在声明有确定长度但没初始化值的变量特别有用。下面这个例子声明了三个变量,前两个已经初始化,最后一个(buffer)没有初始化。head_ptr:.word0;初始化为0tail_ptr:.word0;初始化为0buffer:.skip512;512个字节未初始化请参考.ascii,.asciz,.byte,.hwordand.word等初始化值命令。.text选择该命令以下的内容位于最终可执行文件的text(代码)段。汇编程序指令必须放置在这个段。请参考.data命令的相对详细说明。.wordexpression.4byteexpression在对象文件中插入字(32位),内容为expression的值。可以同时插入多个,以,分隔。这个两个命令是一样的。下面的例子在对象文件中插入8个字节内容。.word0xDEADBEEF;插入字节:0xEF0xBE0xAD0xDE.4byte-42;插入字节0xD60xFF0xFF0xFF;假设小端模式注意ARM微控制器在32位地址边界上,一次总是读取32位数据,换句话说,它不能一次读取32位数据在一个最低两位不为0的地址上。请参考.align命令寻找解决办法。同时参考.byte和.hword命令。这些在其他处理器中不起眼的细节必须记住,在ARM术语中,字表示32位,而非16位。Expressions(表达式)许多ARM汇编指令甚至汇编命令需要不同类型的整数来做操作数,象movr0,#1,需要数字1。可以这么认为,一个表达式任何地方都可能会出现数字。在最基本的层面上,一个表达式可以是一个简单的数字。这个数字可以表现为十进制(不带前缀),十六进制(0x或0X前缀),八进制(以0开头)或者二进制(0b或0B前缀)。它同样可以表现为字符常量,其形式为a或a。下面例子中6行代码都向ro赋相同的值:74。movr0,#74;十进制数74movr0,#0x4A;十六进制数0x4A(0X4A和0x4a是一样的)movr0,#0112;八进制数0112movr0,#0b1001010;二进制数0b1001010(0B1001010是一样的)movr0,#J;字符常量J(首选语法)movr0,#J;字符常量J(备选语法)当然,一个好的程序将用以下的方法来定义一个记号:.setletter_J,J;这是一个实际设计例子movr0,#letter_J字符常量可以像C语言中那样包含无固定顺序的反斜杠,更多细节请参考GNUAssemblerReference的3.6节除简单的整数外,表达式可以看起来像C语言中标准的数学和逻辑表达式一样,GNUAssemblerReference的第六章将详细描述这些方式。下面是一些例子:.setROM_size,128*1024;131072字节(128KB).setstart_ROM,0xE0000000.setend_ROM,start_ROM+ROMsize;0xE0020000.setbm1,0b11001101;二进制掩码(十六进制:0xCD).setval1,-2*4+(45/(510;128(131072右移10位).setval3,bm1|0b11110000;bm1OR0b11110000=0b11111101就像上面的例子一样,表达式同样可以包含已定义的标号。这样,表达式可以产生绝对的值和相对的的值,绝对值和它们在最终文件中的位置无关,是一个简单的数字常量。另一方面,相对值和一些地址(比如说.data的地址)有关,它们的最终位置取决于链接器生成最终可执行文件的时候,和汇编器无关。相对值一般用于计算偏移,并且只能用+和-操作符。以下是例子:.textcode_start:XXX;汇编指令.code_end:.setinstr_size,4;在ARM中指令都是4个字节长.setcode_length,code_end-code_start.setfirst_instr,code_start.setinstr_11th,code_start+10*instr_size.setinstr_10th,instr_11th-instr_sizecode_length标号被设置成一个绝对的值(code_end和code_start的差值)。其他的标号,first_instr,instr_11th和instr_10th的值都取决于.text的值,它们真正的值只有在最终可执行文件生成时才能知道。一般来说,以下规则适用于相对表达式:相对值+绝对值-?相对值绝对值+相对值-?相对值相对值绝对值-?相对值相对值相对值-?绝对值所有其他包括相对值的表达式都是非法的(当然除了简单的标号自身的情况),请注意标号的相对计算只能基于在同一段的标号,比如说你不能得到一个位于.text段的标号和一个位于.data段标号之间的差值。如果你需要,可以找到更多关于相对表达式的信息在GNUAssemblerReference的4.1节。程序例子正像开始时所说的,examples文件夹和它的子文件夹包含很多汇编语言例子程序。这些例子涉及基于ARM微控制器的GNU汇编器各个方面,建议你去学习这些例子,最起码要快速的浏览一遍!特别是examples/intro目录中的那些例子文件,请按下面的顺序学习:simple.s一个简单的ARM汇编程序,可以用它来起步subr.s简单的之程序(函数调用)values.s给寄存器装载常量,使用ldr=pseudo.s更多的信息关于ARM伪指令jumptbl.s分支调

温馨提示

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

评论

0/150

提交评论