GNU ARM 汇编快速了解
中英对照
GNU ARM Assembler Quick Reference
A summary of useful commands and expressions for the ARM architecture using the GNU assembler is presented briefly in the concluding portion of this Appendix. Each assembly line has the following format:
[<label>:] [ <instruction or directive> } @ comment
本文在附录总结了一些有用的arm架构的GNU汇编指令和表达式。每条指令格式如下:
[<标签>:] [<指令>} @ 注释
Unlike the ARM assembler, using the GNU assembler does not require you to indent instructions and directives. Labels are recognized by the following colon instead of their position at the start of a line. An example follows showing a simple assembly program defining a function ‘add’ that returns the sum of two input arguments:
GNU 和ARM汇编不同,GNU汇编不需要进行指令和命令的缩进。label的识别是通过紧跟其后的冒号(“ : ”),而不是判断它是否在一行的开头处。下面的例子展示了add方法的汇编。它返回两个入参的和。
.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 progra
GNU Assembler Directives for ARM
GNU ARM汇编指令
GNU 汇编指令 | 描述 |
.ascii “<string>” | 在汇编中定义字符串(和arm汇编中 DCB伪指令一样 它分配一段字节的内存单元,它每个操作数都占有一个字节,操作数范围为-128~255的数值或字符串) Inserts the string as data into the assembly |
.asciz “<string>” | 和ascii 相同但是不会分配内存 Like .ascii, but follows the string with a zero byte. |
.balign <power_of_2> {,<fill_value> {,<max_padding>} } | 用fill_value 填充 最大 max_padding 各bytes ,填充时按照power_of_2字节对其,power_of_2取值 4、8、16、32等同于 arm汇编的.align |
.byte <byte1> {,<byte2>} … | 按照字节在内存中开辟内存,等价于arm汇编的DCB伪指令 |
.code <number_of_bits> | 设置指令的宽度(设置使用的指令集 ),使用16位thumb指令集或者32位指令集。等同于arm汇编的CODE16和CODE32 |
.if .else .endif | 预编译宏(与armasm中的IF ELSE ENDIF相同) |
.end | 标志汇编文件的结束,一般都会忽略不写 |
.endm | Ends a macro definition – see .macro (similar to MEND in armasm). 结束宏定义 |
.endr | Ends a repeat loop – see .rept and .irp 结束循环 等同于 arm汇编的 WEND |
equ <symbol name>, <value> | This directive sets the value of a symbol (similar to EQU in armasm) 为符号设置值,等同于arm汇编的EQU |
.err | 编译错误报告,将引起编译的终止 |
.exitm | Exit a macro partway through – see .macro (similar to MEXIT in armasm) 中途退出宏 |
.global <symbol> | This directive gives the symbol external linkage (similar to EXPORT in armasm). 这个指令给标签一个外部链接 全局声明标志,这样声明的标号将可以被外部使用。(与armasm中的EXPORT相同)。 |
.hword <short1> {,<short2>} … | 插入一个16-bit的数据队列。(与armasm中的DCW相同) |
.ifdef <symbol> | Makes a block of code conditional. End the block using .endif 标明代码段的条件,使用.endif结束这个代码段 如果 <symbol>被定义,该快代码将被编译。以 .endif结束。 |
.ifndef <symbol> | 如果 <symbol>未被定义,该快代码将被编译。以 .endif结束。 |
.ifdef <symbol> | |
.include “<filename>” | Includes the indicated source file 包含已经声明的源文件 包含文件。(与armasm中的INCLUDE 或者C中的#include一样) |
.irp <param> {,<val_1>} {,<val_2>} … | Repeats a block of code, once for each value in the value list. Mark the end of the block using a .endr directive. In the repeated code block, use \<param> to substitute the associated value in the value list. 循环执行.endr前的代码段,param依次取后面给出的值。 在循环执行的代码段中必须以“\<param> ”表示参数。 |
.macro <name> {<arg_1} {,<arg_2>} … {,<arg_N>} | 定义一段名为name的宏,arg_xxx为参数。 必须有对应的.endm结尾。 可以使用.exitm从中间跳出宏。(与armasm中的MACRO, MEND, MEXIT相同)。 在使用宏参数时必须这样使用:“\<arg>”。 |
.rept <number_of_times> | Repeats a block of code the given number of times 重复给定次数的代码块 |
<register_name> .req <register_name> | 定义一个寄存器,.req的左边是定义的寄存器名,右边是使用的真正使用的寄存器。 (与armasm中的RN类似) acc .req r0 |
.section <section_name> {,”<flags>”} | 开始一个新的代码或数据段。.text, 代码段;.data, 初始化数据段;.bss, 未初始化数据段。 这些段都有缺省的标志(flags),联接器可以识别这些标志。(与armasm中的AREA相同)。 下面是ELF格式允许的段标志 <Flag> Meaning a 允许段 allowable section w writable section x executable section |
.set <variable_name>, <variable_value> | This directive sets the value of a variable. It is similar to SETA in armasm. 为变量赋值 |
.space <number_of_bytes> {,<fill_byte>} | 分配number_of_bytes字节的数据空间,并填充其值为fill_byte,若未指定该值,缺省填充0。 (与armasm中的SPACE功能相同 SPACE 伪指令用于分配一片连续的存储单元,并将该区域初始化为 0 SOFTOOL SPACE 100 ) |
.word <word1> {,<word2>} … | 插入一个32-bit的数据队列。(与armasm中的DCD功能相同) |
GNU ARM汇编特殊字符和语法
代码行中的注释符号: ‘@’
整行注释符号: ‘#’
语句分离符号: ‘;’
直接操作数前缀: ‘#’ 或 ‘$’
.arm 以arm格式编译,同code32
.thumb 以thumb格式编译,同code16
.code16 以thumb格式编译
.code32 以arm格式编译
Register Names
General registers: %r0 - %r15 ($0 = const 0) 通用寄存器 r0 -r15
FP registers: %f0 - %f7 栈寄存器
Non-saved (temp) regs: %r0 - %r3, %r12 临时寄存器,局部寄存器
Saved registers: %r4 - %r10 永久存储寄存器,全局寄存器
Stack ptr register: %sp 堆指针寄存器
Frame ptr register: %fp 堆栈帧指针寄存器: %fp (和SP配合用于调试时backtrace功能)
Link (retn) register: %lr 链接返回寄存器: %lr
一是用来保存子程序返回地址;
二是当异常发生时,LR中保存的值等于异常发生时PC的值减4(或者减2),因此在各种异常模式下可以根据LR的值返回到异常发生前的相应位置继续执行
Program counter: %ip 程序计数器 等价于pc
Status register: $psw 状态寄存器: $psw
Status register flags: xPSR
(x = C current) xPSR_all x 为C时,是当前程序状态寄存器
(x = S saved ) xPSR_f x 为S时, 是备份程序状态寄存器
xPSR_x
xPSR_ctl
xPSR_fs
xPSR_fx
xPSR_fc
xPSR_cs
xPSR_cf
xPSR_cx
.. and so on
Arm Procedure Call Standard (APCS) Conventions
Arm过程调用标准(APCS)约定
Argument registers: %a0 - %a4 (aliased to %r0 - %r4)
参数寄存器: %a0 - %a4 (别名 %r0 - %r4)
Returned value regs: %v1 - %v6 (aliased to %r4 - %r9)
返回值寄存器:%v1 - %v6 (别名 %r4 - %r9)
Addressing Modes
寻址模式
‘rn’ in the following refers to any of the numbered registers, but not the control registers.
'rn'代指除控制寄存器以外的寄存器
addr Absolute addressing mode
addr 绝对地址寻址模式,例如ldr r0,=msg
%rn Register direct
%rn 寄存器直接寻址,使用寄存器存储的值作为指令的参数
[%rn] Register indirect or indexed
[%rn] 寄存器间接寻址或下标寻址,寄存器存储的值是操作数的指针
[%rn,#n] Register based with offset
[%rn,#n] 寄存器基址偏移寻址,例如ldr r0,[%r1, #4]
#imm Immediate data
#imm 操作数在指令中直接使用
Machine Dependent Directives
.arm Assemble using arm mode 汇编使用arm模式
.thumb Assemble using thumb mode 汇编使用thumb模式
.code16 Assemble using thumb mode 汇编使用thumb模式
.code32 Assemble using arm mode 汇编使用arm模式
.force_thumb Force thumb mode (even if not supported) 强制使用thumb模式,即使不支持
.thumb_func Mark entry point as thumb coded (force bx entry) 标记函数的入口点为thumb代码(强制使用bx跳转)
.ltorg Start a new literal pool 标记一个新文字池的开始(文字池:嵌入式代码中用于存放常量的区域)