arm为啥要分两种工作状态:arm和thumb

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了arm为啥要分两种工作状态:arm和thumb相关的知识,希望对你有一定的参考价值。

参考技术A 对于ARM处理器,有两种工作状态分别是ARM工作状态和Thumb工作状态,在这两种工作状态下,对于芯片内部寄存器的使用规则是不同的,所以需要让ARM处理器切换工作状态,b以及bl指令没有状态切换功能,而bx以及blx有,所以c程序与汇编程序相互调用时就需要用这两个指令。你只用b或者bl,只是简单地跳转,而ARM芯片的工作状态没有切换所以会报错 参考技术B 如果处理器是32位的,那么什么情况下用arm什么情况下用thumb?我用汇编写了一段小程序,在c中断用,但是汇编程序的结尾处如果用b
lr不对,用mov
pc
lr也不对,一定要用bx
lr进行状态切换,我就不明白为什么了,难道是c程序在编译时用的状态和汇编程序用的状态不一样?

ARM汇编语言基础

ARM 与 Thumb 寄存器对应关系

  • PC寄存器: ARM状态为R15,Thumb状态为PC
  • LR寄存器: ARM状态为R14,Thumb状态为LR
  • SP寄存器: ARM状态为R13,Thumb状态为SP
  • IP寄存器: ARM状态为R12,Thumb状态为IP
  • FP寄存器: ARM状态为R11,Thumb状态为FP

其他对应关系一一相同

ARM 与 Thumb 指令集

指令格式:

其中

  • opcode为助记符
  • cond为条件
  • S指定其是否影响CPSR寄存器的值(也就是程序状态字)
  • .W与.N指定指令宽带。(一个指定32,一个指定16)
  • Rd 目的寄存器
  • Rn 第一个操作数寄存器
  • operand2为第二个操作数

跳转指令

B 跳转指令

格式:B{cond} label

BL带链接的跳转指令

格式:BL{cond} label

当条件满足时,会将当前指令的下一条指令保存到R14(LR)寄存器中,然后跳转到label中。这通常用于调用子程序,在子程序的尾部,通过 MOV PC,LR 返回

BX 带状态切换的跳转指令

格式:BX{cond} Rm

当执行BX指令时,如果条件cond满足,则处理器会检查Rm的为[0]是否为1,如果为1,这将CSPR寄存器的T置1,并将目标代码解释为Thumb代码来执行。为0的话,复位 CSPR寄存器的T。并将目标代码解释为ARM代码来执行。

eg:

.code 32
ADR R0,thumbcode+1 
BX R0 @跳转到thmbcode,并将处理器切换为thumb模式 
thumbcode:
.code 16
...

BLX带链接与状态切换的跳转指令

格式:BLX{cond} Rm

存储器访问指令

LDR

格式:

LDR{type}{cond} Rd,label

LDRD{cond} Rd,Rd2,label

type指定了操作的数据大小

用于从存储器中加载数据到寄存器。

LDRD 一次加载双字的数据,将数据加载到Rd,Rd2中

STR

格式:

STR{type}{cond} Rd,label

STRD{cond} Rd,Rd2,label

用于储存数据到指定的存储单元

LDM

格式:

LDM{addr_mode}{cond} Rn{!},reglist

其中 ! 为可选,如果有,则将最终地址回写到Rn中

该指令从指定的存储单元,加载数据到寄存器列表中

eg:

LDMIA R0!,{R1-R3} @依次加载R0地址处的数据到R1,R2,R3寄存器中

STM

格式:

STM{addr_mode}{cond} Rn{!},reglist

其中 ! 为可选,如果有,则将最终地址回写到Rn中

将寄存器列表中的数据存储到指定存储单元

PUSH

POP

SWP

格式:

SWP{B}{cond} Rd,Rm,[Rn]

Rd:为要从存储器加载数据的寄存器

Rm:为写入数据到存储器的寄存器

Rn:为存储器地址

如果 Rd 与 Rm 相同,则可实现寄存器与存储器的交换

数据处理指令

以上是关于arm为啥要分两种工作状态:arm和thumb的主要内容,如果未能解决你的问题,请参考以下文章

Thumb指令集程序示例

ARM的编程模式

ARM汇编语言基础

GNU Arm 嵌入式工具链 | arm-none-eabi-gcc 选项:Thumb (-mthumb) 和 Arm (-marm) 状态有啥区别?

为啥要使用thumb模式,与ARM相比较,Thumb代码的两大优势是啥?

有没有办法在 Xcode 4 中为 ARM 而不是 Thumb 编译?