linux 汇编 `.eabi_attribute',ARM处理器寄存器和汇编指令

ARM体系结构支持7种处理器模式,分别是:用户、FIQ、IRQ、管理、中止(abort)、未定义和系统模式。除了用户模式外,其余都称之为特权模式。除了用户和系统模式外,其余都称之为异常模式

寄存器

ARM的寄存器分为两类, 普通寄存器和状态寄存器

普通寄存器总共16个,分别为R0-R15;状态寄存器共2个,分别为CPSR和SPSR寄存器(Reg)寄存器(APCS)作用域含义R0a1所有7种模式工作寄存器

R1a2所有7种模式..

R2a3所有7种模式..

R3a4所有7种模式..

R4v1所有7种模式必须保护

R5v2所有7种模式..

R6v3所有7种模式..

R7v4所有7种模式..

R8v5除FIQ模式..

R9v6除FIQ模式..

R10sl除FIQ模式栈限制

R11fp除FIQ模式帧指针

R12ip除FIQ模式内部过程调用寄存器

R13sp用户和系统模式栈指针

R14lr用户和系统模式连接寄存器

R15pc所有7种模式程序计数器

CPSR--

SPSR-除用户和系统模式-R13(sp): 每一种异常模式都有其自己独立的r13,它通常指向异常模式所专用的堆栈,也就是说五种异常模式、非异常模式(用户模式和系统模式),都有各自独立的堆栈,用不同的堆栈指针来索引。这样当ARM进入异常模式的时候,程序就可以把一般通用寄存器压入堆栈,返回时再出栈,保证了各种模式下程序的状态的完整性。

R14(lr): 每种模式下r14都有自身版组,它有两个特殊功能。保存子程序返回地址。使用BL或BLX时,跳转指令自动把返回地址放入r14中;子程序通过把r14复制到PC来实现返回,通常用下列指令之一:

当异常发生时,异常模式的r14用来保存异常返回地址,将r14如栈可以处理嵌套中断。

PS

ARM处理器中通常将寄存器R13作为堆栈指针(SP)。ARM处理器针对不同的模式,共有6个堆栈指针SP, 其中用户模式和系统模式共用一个SP,每种异常模式都有各自专用的R13寄存器(SP)。它们通常指向各模式所对应的专用堆栈,也就是ARM处理器允许用户程序有六个不同的堆栈空间。这些堆栈指针分别为R13、R13_svc、R13_abt、R13_und、R13_irq、R13_fiq.

2b21a3beb7ab829305486785c3ced3e0.png

汇编指令

存储器访问指令

ARM 处理是加载/存储体系结构的典型的RISC处理器,对存储器的访问只能使用加载和存储指令实现。ARM 的加载/存储指令是可以实现字、半字、无符/有符字节操作;批量加载/存储指令可实现一条指令加载/存储多个寄存器的内容,大大提高效率;SWP指令是一条寄存器和存储器内容交换的指令,可用于信号量操作等。

LDR和STR

加载/存储字和无符号字节指令。使用单一数据传送指令(STR 和LDR)来装载和存储单一字节或字的数据从/到内存。LDR 指令用于从内存中读取数据放入寄存器中;

STR 指令用于将寄存器中的数据保存到内存。1

2

3

4LDR{cond}{T} Rd, ;加载指定地址上的数据(字),放入Rd中

STR{cond}{T} Rd, ;存储数据(字)到指定地址的存储单元,要存储的数据在Rd中

LDR{cond}B{T} Rd, ;加载字节数据,放入Rd中,即Rd最低字节有效,高24位清零

STR{cond}B{T} Rd, ;存储字节数据,要存储的数据在Rd,最低字节有效其中,T 为可选后缀,若指令有T,那么即使处理器是在特权模式下,存储系统也将访问看成是处理器是在用户模式下。T在用户模式下无效,不能与前索引偏移一起使用T立即数1

2

3LDR R1,[R0,#0x12] ;将R0+0x12 地址处的数据读出,保存到R1中(R0 的值不变)

LDR R1,[R0,#-0x12] ;将R0-0x12 地址处的数据读出,保存到R1中(R0 的值不变)

LDR R1,[R0] ;将R0 地址处的数据读出,保存到R1 中(零偏移)

寄存器1

2LDR R1,[R0,R2] ;将R0+R2 地址的数据计读出,保存到R1中(R0 的值不变)

LDR R1,[R0,-R2] ;将R0-R2 地址处的数据计读出,保存到R1中(R0 的值不变)

寄存器及移位常数1

2LDR R1,[R0,R2,LSL #2] ;将R0+R2*4地址处的数据读出,保存到R1中(R0,R2的值不变)

LDR R1,[R0,-R2,LSL #2] ;将R0-R2*4地址处的数据计读出,保存到R1中(R0,R2的值不变)

数据处理指令

跳转指令

状态寄存器指令

ARM协处理器指令

示例分析

源代码1

2

3

4

5

6

7

8

9

10

11

12

13

14#include

int main(int argc, char* argv[])

{

int a = 1;

int b, c;

b = 3;

c = a + b;

printf("Hello c=%d!\n", c);

return 0;

}

编译:1arm-linux-gnueabihf-gcc hello.c -o hello --save-temp

汇编代码1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54.arch armv7-a

.eabi_attribute 28, 1

.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 34, 1

.eabi_attribute 18, 4

.file"hello.c"

.text

.section.rodata

.align2

.LC0:

.ascii"Hello c=%d!\012\000"

.text

.align1

.globalmain

.syntax unified

.thumb

.thumb_func

.fpu vfpv3-d16

.typemain, %function

main:

@ args = 0, pretend = 0, frame = 24

@ frame_needed = 1, uses_anonymous_args = 0

push{r7, lr}

subsp, sp, #24

addr7, sp, #0

strr0, [r7, #4]

strr1, [r7]

movsr3, #1

strr3, [r7, #20]

movsr3, #3

strr3, [r7, #16]

ldrr2, [r7, #20]

ldrr3, [r7, #16]

addr3, r3, r2

strr3, [r7, #12]

ldrr1, [r7, #12]

movwr0, #:lower16:.LC0

movtr0, #:upper16:.LC0

blprintf

movsr3, #0

movr0, r3

addsr7, r7, #24

movsp, r7

@ sp needed

pop{r7, pc}

.sizemain, .-main

.ident"GCC: (Linaro GCC 7.3-2018.05) 7.3.1 20180425 [linaro-7.3-2018.05 revision d29120a424ecfbc167ef90065c0eeb7f91977701]"

.section.note.GNU-stack,"",%progbits@: 单行注释

参考

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值