之一: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, %function main: @ args = 0, pretend = 0, frame = 8 @ frame_needed = 1, uses_anonymous_args = 0 stmfd sp!, {fp, lr} add fp, sp, #4 sub sp, sp, #8 str r0, [fp, #-8] str r1, [fp, #-12] ldr r3, .L3 .LPIC0: add r3, pc, r3 mov r0, r3 bl puts(PLT) mov r3, #0 mov r0, r3 sub sp, fp, #4 ldmfd 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
.arch指定了ARM处理器架构。armv5te表示本程序的代码可以运行在armv5te架构的处理器上运行。
.fpu指定协处理器的类型。softvfp表示使用浮点数运算库来模拟协处理器运算。还可以用vfpv2、vfpv3来指定自带的协处理器。
.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, %function main: @ args = 0, pretend = 0, frame = 8 @ frame_needed = 1, uses_anonymous_args = 0 stmfd sp!, {fp, lr} add fp, sp, #4 sub sp, sp, #8 str r0, [fp, #-8] str r1, [fp, #-12] ldr r3, .L3 .LPIC0: add r3, pc, r3 mov r0, r3 bl puts(PLT) mov r3, #0 mov r0, r3 sub sp, fp, #4 ldmfd 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
三 注释与标号
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指令集。
五 子程序与参数传递
子程序在代码表示一个独立的功能,很多时候,子程序和代码是相同的概念。在汇编中声明函数的方式如下所示:
.global 函数名 .type 函数名 %Function 函数名: ... 函数体 ...
那么函数调用过程中,参数传递的方式如下所示:
ARM汇编中规定:R0~R3这4个寄存器分别用来传递函数调用的第1到第4个参数,超出的参数通过堆栈来传递。R0寄存器用来存放函数调用的返回值。被调用的函数在返回前无需恢复这些寄存器的内容。
关键字:Android ARM 汇编语言 程序结构『本文转载自网络,版权归原作者所有,如有侵权请联系删除』