ARM说简单超简单,说难超级难的,就像英语一样学了十几年都依然是半吊子但又不得不学的一门编程语言

简介

ARM相关,以下所有汇编皆基于armv7

寄存器

  • 总数:37
  • r0: 存储函数参数与返回值
  • r1: 存储函数参数与返回值
  • r2: 存储函数参数与返回值
  • r3: 存储函数参数与返回值
  • r4: 存储局部变量
  • r5: 存储局部变量
  • r6: 存储局部变量
  • r7: 存储局部变量
  • r8: 存储局部变量(仅arm模式)
  • r9: 存储局部变量(仅arm模式)
  • r10: 存储局部变量(仅arm模式)
  • r11: 存储局部变量(仅arm模式)
  • r12: 存储ip
  • r13: 存储sp
  • r14: 存储lr
  • r15: 存储pc
  • cpsr[31]:n(negative)
  • cpsr[30]😒(zero)
  • cpsr[29]:c(carry)
  • cpsr[28]:v(overflow)
  • cpsr[27]:保留位
  • cpsr[26]:保留位
  • cpsr[25]:保留位
  • cpsr[24]:保留位
  • cpsr[23]:保留位
  • cpsr[22]:保留位
  • cpsr[21]:保留位
  • cpsr[20]:保留位
  • cpsr[19]:保留位
  • cpsr[18]:保留位
  • cpsr[17]:保留位
  • cpsr[16]:保留位
  • cpsr[15]:保留位
  • cpsr[14]:保留位
  • cpsr[13]:保留位
  • cpsr[12]:保留位
  • cpsr[11]:保留位
  • cpsr[10]:保留位
  • cpsr[9]: 保留位
  • cpsr[8]: 保留位
  • cpsr[7]:存储IRQ中断禁止位 1:禁止,0:允许
  • cpsr[6]:存储FIQ中断禁止位 1:禁止,0:允许
  • cpsr[5]:存储工作状态位 0:arm,1:thumb
  • cpsr[4,3,2,1,0]:0b10000(用户user)
  • cpsr[4,3,2,1,0]:0b10001(fiq)
  • cpsr[4,3,2,1,0]:0b10010(irq)
  • cpsr[4,3,2,1,0]:0b10011(管理svc)
  • cpsr[4,3,2,1,0]:0b10111(中止abort)
  • cpsr[4,3,2,1,0]:0b11011(未定义und)
  • cpsr[4,3,2,1,0]:0b11111(系统sys)
  • spsr(fiq):存储中断前cpsr
  • spsr(svc):存储中断前cpsr
  • spsr(abt):存储中断前cpsr
  • spsr(irq):存储中断前cpsr
  • spsr(und):存储中断前cpsr

栈平衡

参数只能存放于r0-r3寄存器里,其余的从右往左依次压入栈上,并且由被调用者执行出栈操作,实现栈平衡,参数存放顺序如下:

[r0:arg0][r1:arg1][r2:arg2][r3:arg3][sp:arg4][sp+4:arg5][sp+8:arg6]

当然这只是一种约定,并不一定非得这样

PUSH与POP

push {r4,r5,r6,lr}

其实相当于

sub sp,sp,#16   ;16=4*4
str lr,[sp, #12]
str r6,[sp, #8]
str r5,[sp, #4]
str r4,[sp, #0]

POP就是与PUSH相反操作即可

指令解析

EOR.W           R3, R3, R3,LSR#6 

对应c伪代码

r3=r3^(r3>>6)
str     r3, [r2, r1, lsl #2] 
ldr     r3, [r2, r1, lsl #2] 

对应c伪代码

r2[r1]=r3;//r2为32位整型数组
r3=r2[r1];

这里的汇编会有<<2操作,是因为整形占4字节,<<2也就是*4,c里面的索引是按整形来数的,而汇编里是按字节来数的,所以需要*4

指令分段

c里面各种语句可以分为几大类:变量定义,赋值,函数调用,所以可以在汇编找ldr,str,b等指令,根据这些指令进行分段,每段相当于c里一条语句

求余运算

汇编里的求余运算根据数值不同,五花八门,比如下面这个例子:

7811696bf0de4acafdf978731712af6

指令优化

gcc在进行编译时,会进行各种复杂的优化,以提升执行效率,具体各种优化请参考:Here

  • 函数内联

image

  • 指令段交叉

最后一步str赋值会穿插到下一段指令中

image

  • 循环展开

STR与LDR

image

  • 参考:https://blog.csdn.net/wh8_2011/article/details/53130932

LDM与STM

详细参考:Here

其他指令

辅助工具

  • 代码即时编译工具:https://godbolt.org/

image

  • 代码即时运行调试工具:https://github.com/linouxis9/ARMStrong

image

参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jitcor

觉得有用,不赏点?

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值