章节列表
之一:ARM汇编语言开篇
之二:C/C++程序生成ARM汇编程序的进程剖析
之三:ARM汇编语言程序结构
之四:ARM处理器的寻址方法
之五:ARM指令集与Thumb指令集
之六:NEON指令集与VFP指令集
Android渠道的ARM汇编是GNU ARM汇编格局,运用的汇编器是GAS(GNU Assembler),GAS有自己的一套语法结构。具体的内容能够查阅GAS语法结构官方手册。
咱们先来看一个完好的ARM汇编程序:
C代码:
#includeint main(int argc, char* argv[]){printf("Hello ARM!\n");return 0;}
对应的汇编代码:
.arch armv5te.fpu softvfp.eabi_attribute 20, 1.eabi_attribute 21, 1.eabi_attribute 23, 3.eabi_attribute 24, 1.eabi_attribute 25, 1.eabi_attribute 26, 2.eabi_attribute 30, 6.eabi_attribute 18, 4.file "hello.c".section .rodata.align 2.LC0:.ascii "Hello ARM!\000".text.align 2.global main.type main, %functionmain:@ args = 0, pretend = 0, frame = 8@ frame_needed = 1, uses_anonymous_args = 0stmfd sp!, {fp, lr}add fp, sp, #4sub sp, sp, #8str r0, [fp, #-8]str r1, [fp, #-12]ldr r3, .L3.LPIC0:add r3, pc, r3mov r0, r3bl puts(PLT)mov r3, #0mov r0, r3sub sp, fp, #4ldmfd sp!, {fp, pc}.L4:.align 2.L3:.word .LC0-(.LPIC0+8).size main, .-main.ident "GCC: (GNU) 4.4.3".section .note.GNU-stack,"",%progbits
下面分部分介绍这段代码的结构。
一 处理器架构界说
.arch armv5te @处理器架构.fpu softvfp @协处理器类型.eabi_attribute 20, 1 @接口特点.eabi_attribute 21, 1.eabi_attribute 23, 3.eabi_attribute 24, 1.eabi_attribute 25, 1.eabi_attribute 26, 2.eabi_attribute 30, 6.eabi_attribute 18, 4
1.1 处理器架构
.arch指定了ARM处理器架构。armv5te表明本程序的代码能够运转在armv5te架构的处理器上运转。
1.2 协处理器类型
.fpu指定协处理器的类型。softvfp表明运用浮点数运算库来模仿协处理器运算。还能够用vfpv2、vfpv3来指定自带的协处理器。
1.3 接口特点
.eabi_attrbute指定了一些接口。
EABI(Embedded Application Binary Interface)嵌入式运用二级制接口是ARM指定的一套接口标准,Android体系完成了它。
二 段界说
.file "hello.c".section .rodata.align 2.LC0:.ascii "Hello ARM!\000".text.align 2.global main.type main, %functionmain:@ args = 0, pretend = 0, frame = 8@ frame_needed = 1, uses_anonymous_args = 0stmfd sp!, {fp, lr}add fp, sp, #4sub sp, sp, #8str r0, [fp, #-8]str r1, [fp, #-12]ldr r3, .L3.LPIC0:add r3, pc, r3mov r0, r3bl puts(PLT)mov r3, #0mov r0, r3sub sp, fp, #4ldmfd sp!, {fp, pc}.L4:.align 2.L3:.word .LC0-(.LPIC0+8).size main, .-main.ident "GCC: (GNU) 4.4.3".section .note.GNU-stack,"",%progbits
ARM中段的界说格局如下所示:
.section name , "flags", %type, flag_specific_arguments
- name:段名
- flags:段的特点,如读、写和可执行等。
- type:段的类型,如progbits表明段中含有数据,note表明段中包括的数据并非程序自身运用。
- flag_specific_arguments:指定了一些渠道相关的参数。
三 注释与标号
GNU ARM支撑两种注释增加方法。
/* */型注释
/* args = 0, pretend = 0, frame = 8 *//* frame_needed = 1, uses_anonymous_args = 0 */
@型注释
@ args = 0, pretend = 0, frame = 8@ frame_needed = 1, uses_anonymous_args = 0
四 汇编器指令
.file "hello.c".section .rodata.align 2.LC0:.ascii "Hello ARM!\000".text.align 2.global main.type main, %function
程序中所有以.最初的指令都是汇编器指令,汇编器指令是与汇编器相关的,它们并不归于ARM指令集。
- .file:指定源文件名。
- .align:指定代码的对齐方法,后边跟的数值是2的次数方。
- .ascii:声明字符串。
- .global:声明大局符号,大局符号是指在本程序外能够拜访的符号,
- .type:指定符号的类型。
- .word:用来寄存地址值。
- .size:设置指定符号的巨细。
- .ident:编译器标识,无实践用处。
五 子程序与参数传递
子程序在代码表明一个独立的功用,许多时分,子程序和代码是相同的概念。在汇编中声明函数的方法如下所示:
.global 函数名.type 函数名 %Function函数名:...函数体...
那么函数调用进程中,参数传递的方法如下所示:
ARM汇编中规则:R0~R3这4个寄存器别离用来传递函数调用的第1到第4个参数,超出的参数经过仓库来传递。R0寄存器用来寄存函数调用的回来值。被调用的函数在回来前无需康复这些寄存器的内容。