1. ARM汇编寄存器
ARM微处理共有37个32位寄存器,其中31个为通用寄存器,6个为状态寄存器。ARM处理器支持7种运行模式,分别为:用户模式、快速中断模式、外部中断模式、管理模式、数据访问终止模式、系统模式、未定义指令中止模式。
在用户模式下,处理器可以访问的寄存器为不分组寄存器R0~R7, 分组寄存器R8-R14,程序计数器R15(PC)以及当前程序状态寄存器CPSR.
ARM处理器有两种工作状态:ARM状态与Thumb状态,可以随意切换,当处理器处理ARM状态时,会执行32位字对齐的ARM指令,当处于Thumb状态时,执行的是16位对齐的Thumb指令。对应关系如下:
- Thumb状态 R0~R7 = ARM状态的R0-R7
- Thumb状态CPSR = ARM状态的CPSR
- Thumb状态 FP/IP/SP/LR/PC对应ARM状态的R11/R12/R13/R14/R15
2. ARM汇编语言程序结构
ARM汇编程序语言主要包括段定义、注释与标号、汇编指令
以hello.c的汇编为例:
#include <stdio.h>
int main(int argc, char* argv[]){
printf("Hello ARM!\n");
return 0;
}
hello.S
@@=======================
@@处理器架构定义
.arch armv7te @处理器架构,表示本程序可在armv7架构的处理器上运行
.fpu softvfp @softvfp表示浮点运算用软模拟完成,vfpv2/vfpv3来指定使用字代
@表的协处理器
.eabi_attribute 20, 1 @.eabi_attribute指定了一些接口属性,
.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
@@处理器架构定义
@@=======================
@@=======================
@@段定义 //.section name[,"flags[,%type[,flag_specific_aguments]]]
.file "hello.c" @指定原文件名为hello.c
.section .rodata @.rodata表示被编译的是只读数据段, 属性默认
.align 2 @代码对齐方式,后面跟的数值为2的次数方, 表示2^2字节对齐
.LC0:
.ascii "Hello ARM!\000" @声明字符串
.text @定义了代码段,没有使用.section关键字
.align 2 @代码对齐方式,后面跟的数值为2的次数方, 表示2^2字节对齐
.global main @声明全局符号,在本程序外可访问符号
.type main, %function @指定符号的类型,main,%function表示main符号为函数
@@段定义
@@========================
@@========================
@@汇编指令
main: @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) @用来存放地址值,.LCO-(.LPIC0+8)用来存放一个与地址无关的偏移量
.size main, .-main @设置指定符号的大小,.表示当前地址减去main符号的地址为整个main函数的大小
.ident "GCC: (GNU) 4.4.3" @编译器标识,生成可执行程序后它的值放置到"comment"字段中
.section .note.GNU-stack,"",%progbits @定义.note.GNU-stack段,它的作用禁止生成可执行堆栈