GNU ARM Assembler Quick Reference
GNU ARM 汇编简明参考手册
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.
在本附录的最后部分简要介绍了使用GNU汇编程序的ARM体系结构的有用命令和表达式。
Each assembly line has the following format:
[<label>:] [<instruction or directive>} @ comment
没一行汇编代码都遵循如下的格式:
[<标号>:] [<指令或伪操作>} @ 注释
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.
与ARM汇编程序不同,使用GNU汇编程序不需要在指令或伪操作前缩进。标号由跟随在其后的“:”识别,而不是其在行首的位置。
An example follows showing a simple assembly program defining a function ‘add’ that returns the sum of
two input arguments:
.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 program
一个返回两个参数和的‘add’函数例子:
.section .text, “x”
.global add @ 赋予add符号外部链接属性
add:
ADD r0, r0, r1 @ r0 r1是传入的参数,可以搜索gnu eabi来获取更多信息
MOV pc, lr @ lr存储了返回的指令地址,将lr赋值给pc就会从子程序返回
@ 程序结束
GNU Assembler Directives for ARM
ARM GNU 汇编伪操作
The follow is an alphabetical listing of the more command GNU assembler directives.
下表是按字母顺序排序的常见GNU 汇编伪操作
GNU Assembler Directive Description
GNU 汇编为操作 描述
.ascii “<string>” Inserts the string as data into the assembly (like DCB in armasm).
.ascii "<字符串>" 将字符串作为数据插入,可以通过添加一个标号引用它
hello:
.ascii "hello"
.asciz “<string>” Like .ascii, but follows the string with a zero byte.
.asciz "<字符串>" 和.ascii很像,但是会在字符串结尾附加'\0'
.balign <power_of_2> Aligns the address to <power_of_2> bytes. The assembler
{,<fill_value> aligns by adding bytes of value <fill_value> or a suitable default.
{,<max_padding>} } The alignment will not occur if more than <max_padding> fill
bytes are required (similar to ALIGN in armasm).
.balign <2的幂次>
{,<填充字节> 对齐地址到<2的幂次>的整倍数。汇编工具用<填充字节>或一个恰当的默认字节
{,<最大填充字节数>} } 从当前地址填充到对齐地址。需要填充的字节如果超过了<最大填充字节数>
对齐操作不会执行
.byte <byte1> {,<byte2>} ... Inserts a list of byte values as data into the assembly (like DCB in armasm).
.byte <字节1> {,<字节2>} ... 将一列单字节范围的数值作为数据插入
.code <number_of_bits> Sets the instruction width in bits. Use 16 for Thumb and 32 for
ARM assembly (similar to CODE16 and CODE32 in armasm).
.code <bit位数> 设定指令的宽度为<bit位数>位。Thumb为16,ARM为32。
.else Use with .if and .endif (similar to ELSE in armasm).
.else 和 .if 和 .endif 一起使用
.end Marks the end of the assembly file (usually omitted).
.end 标记汇编文件的结尾,一般会被省略
.endif Ends a conditional compilation code block – see .if, .ifdef, .ifndef (similar to ENDIF in armasm).
.endif 标记条件编译代码块的结束 - 参见 .if,.ifdef,.ifndef
.endm Ends a macro definition – see .macro (similar to MEND in armasm).
.endm 标记宏定义的结束 - 参见 .macro
.endr Ends a repeat loop – see .rept and .irp (similar to WEND in armasm).
.endr 结束一个重复循环 - 参见 .rept 和 .irp
.equ <symbol name>, <value> This directive sets the value of a symbol (similar to EQU in armasm)
.equ <标记名>, <数值> 这个伪指令设置<标记名>为<数值>,注意这里没有作为数据插入
.err Causes assembly to halt with an error.
.err 停止汇编操作并报错
.exitm Exit a macro partway through – see .macro (similar to MEXIT in armasm)
.exitm 在一个宏代码块的中间提前退出 - 参考 .macro
.global <symbol> This directive gives the symbol external linkage (similar to EXPORT in armasm).
.global <标记> 这条伪操作使<标记>可以被外部链接
.hword <short1> {,<short2>} Inserts a list of 16-bit values as data into the assembly (similar to DCW in armasm).
...
.hword <short1> {,<short2>} 将一列两字节范围的数值作为数据插入
...
.if <logical_expression> Makes a block of code conditional. End the block using .endif
(similar to IF in armasm). See also .else.
.if <逻辑表达式> 根据<逻辑表达>真假决定是否执行紧随其后的代码块。使用.endif标记这个代码块的结束。
同时参考 .else.
.ifdef <symbol> Include a block of code if <symbol> is defined. End the block with .endif.
.ifdef <标记> 如果<标记>被定义那么就包含紧随其后的代码块。使用.endif标记这个代码块的结束。
.ifndef <symbol> Include a block of code if <symbol> is not defined. End the block with .endif.
.ifndef <标记> 如果<标记>没有被定义那么就包含紧随其后的代码块。使用.endif标记这个代码块的结束。
.include “<filename>” Includes the indicated source file (similar to INCLUDE in armasm or #include in C).
.include “<文件名>” 包含<文件名>指定的源文件到当前文件中。
.irp <param> {,<val_1>} Repeats a block of code, once for each value in the value list.
{,<val_2>} ... 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.
.irp <param> {,<val_1>} 为每一个{,<val_n>}数值执行一次紧随其后的代码块,使用.endr标记这个代码段块的结束。
{,<val_2>} ... 在这个代码段中,可以通过\<param>来引用当前的{,<val_n>}的值。
.macro <name> {<arg_1} Defines an assembler macro called <name> with N parameters.
{,<arg_2>} ... {,<arg_N>} The macro definition must end with .endm. To escape from the
macro at an earlier point, use .exitm. These directives are
similar to MACRO, MEND, and MEXIT in armasm. You must
precede the dummy macro parameters by \. For example:
.macro SHIFTLEFT a, b
.if \b < 0
MOV \a, \a, ASR #-\b
.exitm
.endif
MOV \a, \a, LSL #\b
.endm
.macro <name> {<arg_1}
{,<arg_2>} ... {,<arg_N>} 看这个例子就行了
.macro SHIFTLEFT a, b
.if \b < 0
MOV \a, \a, ASR #-\b
.exitm
.endif
MOV \a, \a, LSL #\b
.endm
.rept <number_of_times> Repeats a block of code the given number of times. End with .endr.
.rept <次数> 重复执行一个代码块<次数>次,该代码块以.endr标记结束。
<register_name> .req This directive names a register. It is similar to the RN directive
<register_name> in armasm except that you must supply a name rather than a
number on the right (e.g., acc .req r0).
<register_name> .req 这个伪指令命名一个寄存器。(例如,acc .req r0)。
<register_name>
.section <section_name> Starts a new code or data section. Sections in GNU are called
{,”<flags>”} .text, a code section, .data, an initialized data section, and
.bss, an uninitialized data section. These sections have default
flags, and the linker understands the default names (similar
directive to the armasm directive AREA). The following are
allowable .section flags for ELF format files:
<Flag> Meaning
a allowable section
w writable section
x executable section
.section <段名> 标记一个新的code或data段的开始。
{,”<属性标志>”} GNU段名 描述
.text a code section
.data an initialized data section, and
.bss an uninitialized data section.
这些段都有默认的属性标识,连接器可以识别处理这些默认的段名的属性
以下是允许的ELF格式文件的段属性标志
<标志> 含义
a 段需要占用内存
w 段可写
x 段可执行
.set <variable_name>, This directive sets the value of a variable. It is similar to SETA in armasm.
<variable_value>
.set <变量名>, 设置<变量名>为的值为<变量值>
<变量值>
.space <number_of_bytes> Reserves the given number of bytes. The bytes are filled with
{,<fill_byte>} zero or <fill_byte> if specified (similar to SPACE in armasm).
.space <字节数> 保留<字节数>个字节的空间,并用<填充字节>填充,如果没有指定<填充字节>则填充0。
{,<填充字节>}
.word <word1> {,<word2>} ... Inserts a list of 32-bit word values as data into the assembly(similar to DCD in armasm).
.word <word1> {,<word2>} ... 将一列32-bit范围的数值作为数据插入
Assembler Special Characters / Syntax
汇编器特殊字符及语法
Inline comment char: ‘@’
代码中的注释符号:'@'
Line comment char: ‘#’
整行注释符号:'#'
Statement separator: ‘;’
语句分割符:';'
Immediate operand prefix: ‘#’ or ‘$’
直接操作数前缀:'#' 或 '$'
Register Names
寄存器名
General registers: %r0 - %r15 ($0 = const 0)
通用寄存器: %r0 - %r15
FP registers: %f0 - %f7
FP寄存器: %f0 - %f7 (没有查到功能)
Non-saved (temp) regs: %r0 - %r3, %r12
临时寄存器(caller saved): %r0 - %r3,%r12
Saved registers: %r4 - %r10
全局寄存器(callee saved): %4 - %r10
Stack ptr register: %sp
堆栈指针寄存器: %sp
Frame ptr register: %fp
堆栈帧指针寄存器: %fp (和SP配合用于调试时backtrace功能)
Link (retn) register: %lr
链接返回寄存器: %lr (一是用来保存子程序返回地址;
二是当异常发生时,LR中保存的值等于异常发生时PC的值减4(或者减2),
因此在各种异常模式下可以根据LR的值返回到异常发生前的相应位置继续执行)
Program counter: %ip
程序计数器: %ip (应该是原文件错了,这里是%pc,ip应该指Intra-Procedure-call Scratch Register)
Status register: $psw
状态寄存器: $psw
Status register flags: xPSR
状态寄存器标识: xPSR
(x = C current) xPSR_all
(x = S saved ) xPSR_f
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 汇编使用arm模式
.thumb Assemble using thumb mode
.thumb 汇编使用thumb模式
.code16 Assemble using thumb mode
.code16 汇编使用thumb模式
.code32 Assemble using arm mode
.code32 汇编使用arm模式
.force_thumb Force thumb mode (even if not supported)
.force_thumb 强制使用thumb模式,即使不支持
.thumb_func Mark entry point as thumb coded (force bx entry)
.thumb_func 标记函数的入口点为thumb代码(强制使用bx跳转)
.ltorg Start a new literal pool
.ltorg 标记一个新文字池的开始(文字池:嵌入式代码中用于存放常量的区域)
Opcodes
For detailed information on the machine instruction set, see this manual:
更多关于机器指令集的详细信息请参考这些手册:
ARM Architecture Reference Manual, Addison-Wesley ISBN 0-201-73719-1
Here is a recommended book to get a lot of system developer information on the ARM architecture.
ARM System Developer’s Guide, Morgan Kaufmann Publishers ISBN 1-55860-874-5 (alk.paper), authors:
Andrew N. Sloss, Dominic Symes, Chris Wright, 2004