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

下载本文档

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

文档简介

1、ARM标准汇编与GNU汇编前段时间看arm的汇编,发现很多有一个小点,但是借来的书上的语法却没有,问同学也 不知道, 于是在网上查了一番才发现我书上看到的是arm的标准汇编, 而有小点的gnu的 汇编,于是将收集到的资料整理后放到这里来。GNU汇编 语言结构主要包括三个常用的段:databsstext数据段 声明带有初始值的元素数据段 声明使用0或者null初始化的元素正文段 包含的指令,每个汇编 程序都必须包含此段使用.section指令定义段,如:.section .data.section .bss.section .text起始点:gnu汇编器使用_start标签表示默认的起始点,此外

2、如果想要 汇编内部的标签能够被 外部程序访问,需要使用.globl指令,如:. globl _start使用通用库函数时可以使用:ld -dynamic-linker /lib/ld-linux.so.2II II II II II II II II II II II II II II II II II II II II II II II II II II II II II II II II II II II II II II II II II II II II II II II IIa a a a a a a a a a a a a a a a a a a a a a a a a a a a

3、 a a a a a a a a a a a a a a a a a a a aa a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a aa a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a#四,数据传递a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a

4、 a a a a a a a a a a a a a a a aa a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a aa a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a

5、 a a a a a a a a a1,数据段使用.data声明数据段,这个段中声明的任何数据元素都保留在内存中并可以被 汇编 程序的指令读取,此外还可以使用.rodata声明只读的数据段,在声明一个数据元素时,需要使用标签和 命令:标签:用做引用数据元素所使用的标记, 它和c语言的变量很相似,它对于处理器是没 有意义的,它只是用做 汇编 器试图访问内存位置时用做引用指针的一个位置。指令:指示 汇编器为通过标签引用的数据元素保留特定数量的内存, 声明命令之后必须 给出一个或多个默认值。声明指令:.ascii文本字符串.asciz以空字符结尾的字符串.byte字节值.doubIe双精度浮点值.f

6、Ioat单精度浮点值.int32位整数.Iong32位整数,和int相同.octa16字节整数.quad8字节整数.short16位整数.singIe单精度浮点数(和fIoat相同)例子:output:.ascii hello world.pi:.float 2.14声明可以在一行中定义多个值,如: ages:.int 20, 10, 30, 40定义静态符号:使用.equ命令把常量值定义为可以在文本段中使用的符号,如.section .data.equ LINUX_SYS_CALL, 0 x80.section .textmovl $LINUX_SYS_CALL, %eax2, bss段和d

7、ata段不同,无需声明特定的数据类型,只需声明为所需目的保留的原始内存部分 即可。GNU汇编 器使用以下两个命令声明内存区域:.comm.Icomm声明为未初始化的通用内存区域 声明为未初始化的本地内存区域两种声明很相似, 但.Icomm是为不会从本地 汇编代码之外进行访问的数据保留的,格式 为:.comm/.lcomm symbol, length例子:.section .bss.lcomm buffer, 1000该语句把1000字节的内存地址赋予标签buffer,在声明本地通用内存区域的程序之外 的函数是不能访问他们的.(不能在. globl命令中使用他们)在bss段声明的好处是,数据不

8、包含在可执行文件中。在数据段中定义数据时,它必须 被包含在可执行程序中,因为必须使用特定值初始化它。 因为不使用数据初始化bss段中声 明的数据区域,所以内存区域被保留在运行时使用,并且不必包含在最终的程序中。3, 传送数据move指令:格式movex源操作数,目的操作数。l用于32位的长字节w用于16位的字b用于8位的字节值立即数前面要加一个$符号,寄存器前面要加%符号。8个通用的寄存器是用于保存数据的最常用的寄存器,这些寄存器的内容可以传递给其他的任何可用的寄存器。的内容只能传送给通用寄存器和通用寄存器不同,专用寄存器(控制,调试,段) ,或者接收从通用寄存器传过来的内容。在对标签进行引用

9、时例:.section .datavalue:.int 100_start:movl value, %eax movl $value, %eax movl %ebx, (%edi) movl %ebx, 4(%edi)只是把标签value当前引用的内存值传递给eax把标签value当前引用的内存地址指针传递给eax如果edi外面没有括号那么这个指令只是把ebx中的值加载到edi中,如果有了括号就表示把ebx中的内容 传送给edi中包含的内存位置。其中x为要传送数据的长度,取值有:其中:movl value, %eaxmovl $value, %eax movl%ebx, (%edi)movl

10、%ebx, 4%edi)表示把edi中的值放在edi指向的位置之后的4字节内存位置中movl %ebx, -4 (%edi)存位置中表示把edi中的值放在edi指向的位置之前的4字节内cmove指令(条件转移):cmovex源操作数,目的操作数. x的取值为无符号数:a/nbe大于/不小于或者等于ae/nb大于或者等于/不小于nc无进位b/nae小于/不大于等于c进位be/na小于或等于/不大于e/z等于/零ne/nz不等于/不为零p/pe奇偶校验/偶校验np/po非奇偶校验/奇校验有符号数:ge/nl大于或者等于/不小于l/nge小于/不大于或者等于le/ng小于或者等于/不大于o溢出no未

11、溢出s带符号(负)ns无符号(非负)交换数据:xchg在两个寄存器之间或者寄存器和内存间交换值如:xchg操作数,操作数,要求两个操作数必须长度相同且不能同时都是内存位置其中寄存器可以是32,16,8位的bswap反转一个32位寄存器的字节顺序如: bswap %ebxxadd交换两个值 并把两个值只和存储在目标操作数中如: xadd源操作数,目标操作数其中源操作数必须是寄存器,目标操作数可以是内存位置也可以是寄存器其中寄存器可以是32,16,8位的cmpxchgcmpxchg source, destination其中source必须是寄存器, destination可以是内存或者寄存器,用

12、来比较 两者的值,如果相等,就把源操作数的值加载到目标操作数中,如果不等就把 目标操作数加载到源操作数中,其中寄存器可以是32,16,8位的,其中源操作数是EAX,AX或者AL寄存器中的值cmpxchg8b同cmpxchg, 但是它处理8字节值, 同时它只有一个操作数cmpxchg8bdestination其中destination引用一个内存位置,其中的8字节值会与EDX和EAX寄存器中 包含的值(EDX高位寄存器, EAX低位寄存器)进行比较,如果目标值和EDX:EAX对中的值相等,就把EDX:EAX对中的64位值传递给内存位置,如果不匹配就把 内存地址中的值加载到EDX:EAX对中4,堆

13、栈ESP寄存器保存了当前堆栈的起始位置,当一个数据压入栈时, 它就会自动递减 反之其自动递增压入堆栈操作:pushx source, x取值为:l 32位长字w 16位字弹出堆栈操作:popx source其中source必须是16或32位寄存器或者内存位置,当pop最后一个元素时ESP值 应该和以前的相等5,压入和弹出所有寄存器pusha/popa压入或者弹出所有16位通用寄存器pushad/popad压入或者弹出所有32位通用寄存器pushf/popf压入或者弹出EFLAGS寄存器的低16位pushfd/popfd压入或者弹出EFLAGS寄存器的全部32位6,数据地址对齐gas汇编 器支持

14、.align命令, 它用于在特定的内存边界对准定义的数据元素, 在数 据段中.align命令紧贴在数据定义的前面比较:cmp operend1, operend2进位标志修改指令:CLC清空进位标志(设置为0)CMC对进位标志求反(把它改变为相反的值)STC设置进位标志(设置为1)循环:loop循环直到ECX寄存器为0loope/loopz循环直到ecx寄存器为0或者没有设置ZF标志loopne/loopnz循环直到ecx为0或者设置了ZF标志指令 格式 为: loopxx address注意循环指令只支持8位偏移地址另有一个比较篇的如下:ARM汇编和Gnu汇编的转换将ARM ADS下的汇编码

15、移植到GCC for ARM编译器时,有如下规则:1,注释行以或/* . */代替;2, GET或INCLUDE = .INCLUDE如:get option.a = .include option.a3, EQU = .equTCLK2 EQU PB25 = .equ TCLK2, PB25 SETA = .equSETL = .equBUSWIDTH SETA 16 = .equ BUSWIDTH, 164, EXPORT = .globalIMPORT = .externGBLL = .globalGBLA = .global5, DCD = .long6, IF :DEF: = .IF

16、DEF ELSE = .ELSE ENDIF = .ENDIF :OR: = |:SHL: = .endNOTE:在被include的头文件中,如option.a中,不再需要.end,否则会导致主汇编程 序结束。8,符号定义加:号Entry = Entry: AREA Word, CODE, READONLY = .text AREA Block,DATA, READWRITE = .data CODE32= .armCODE16= .thumb9,MACRO = .macroMEND = .endm开始看start.s中的代码, 又一句.balignl 16,0 xdeadbeef,不知什么

17、意思, 网上搜了一下了解到这条命令的作用如下:.balignwl abs-expr, abs-expr, abs-expr增加位置计数器(在当前子段)使它指向规定的存储边界。 第一个表达式参数(结果必须是 纯粹的数字)是必需参数:边界基准,单位为字节。例 如,.balign 8向后移动位置计数器 直至计数器的值等于8的倍数。如果位置计数器已经是8的倍数,则无需移动。 第2个表达 式参数(结果必须是纯粹的数字)给出填充字节 的值,用这个值填充位置计数器越过的地方。 第2个参数(和逗点)可以省略。如果省略它,填充字节的值通常是0。 但在某些系统上,如果本段标识为包含代码, 而填充值被省略,则使用no-op指令填充空白区。第3个参数的结 果也必须是纯粹的数字, 这个参数是可选的。 如果存在第3个参数, 它代表本对齐命令允许 跳过字节数的最大值。 如果完成这个对齐需要跳过的字

温馨提示

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

评论

0/150

提交评论