嵌入式系统软件结构的四个层面

  • 板级支持包(BSP,隔离了所支持的嵌入式操作系统与底层硬件平台之间的相关性)
  • 实时操作系统(RTOS)层
  • 应用程序接口(API)层
  • 应用程序层

ARM技术特征

  • Load/Store 体系结构
  • 固定的32位指令
  • 3地址指令格式

(具有T变种的)ARM两种工作状态:ARM状态、Thumb状态

ARM七种工作模式

ARM处理器共有37个寄存器,31个通用寄存器,6个状态寄存器(CPSR、… )

批量数据加载/存储指令:

在这里插入图片描述

[例题]要求用STM和LDM语句, 实现寄存器间的数据传送。如:R0->R2, R1->R3, R2 -> R4, R3->R5, R4->R6, R5->R7, R6 ->R0, R7->R1。

约定:编号低的寄存器在存储/加载数据时,对应于存储器的低地址。

1
2
3
STMIA	R8!, {R0-R7}
LDMDB R8!, {R0-R1} ;因为R8指向的是原R7数据的下一个单元
LDMDB R8!, {R2-R7}
1
2
MVN R1, R2 ;将R2取反,结果存入R1
SWP R1, R2, [R3] ;将R3所指向的存储器中的字数据传送到R1,将R2字数据传送到R3所指向的存储单元

在ARM微处理器的数据传送中,数据的源和数据的目标只有两种:一种是ARM的寄存器R0~R15;另一种就是外部存储器(它们可能是外围模块的寄存器、外部数据存储器或可访问的程序存储器等)

ARM微处理器内部没有RAM,而ARM除了寄存器(即R0~R15)外没有别的存储单元;在以ARM为核的嵌入式系统中,所有的外围模块都和存储单元一样,是ARM微处理器的不同的地址单元。

1
2
3
4
5
6
7
8
9
10
11
LDR R3, [R1, R2, LSL#3]! 
; R3 <- [R1+R2*8] 然后 R1 <- R1+R2*8

LDR R3, [R1], R2
; R3 <- [R1] 然后 R1 <- R1+R2

LDR R3,[R1],R2,LSL#3
; R3 <- [R1] 然后 R1 <- R1+R2*8

STRH R3, [R1, #8]
;将寄存器R3中半字数据写入到R1+8为地址的存储器中

有效立即数:

当参与操作的第 2 操作数为立即数时,每个立即数采用一个8位常数,循环右移偶数位(其位数由一个 4位 二进制数的两倍)而间接得到的

1
2
3
4
MOV	R1,#0xC000	;0xC000可由0x03循环右移16位得到

0x4000003B0xED循环右移2位)
0x0016C0000x5B循环右移18位)

非法的8位图立即数,例如:0x0103C000

条件码

小于大于小于等于(≤)大于等于(≥)
有符号LTGTLEGE
无符号LOHILS:lower or sameHS:higher or same

当然,CS 也能表示 无符号≥,CC 能表示 无符号<

带进位加法指令以及带借位减法指令

1
2
ADC R2, R2, R4 ;R2 <- R2+R4+C
SBC R2, R2, R4 ;R2 <- R2-R4-C

反减法指令

1
2
RSB R0, R1, R2 ;R0 <- R2 - R1
RSB R0, R2, R3, LSL#1 ;R0 <- R3*2-R2

位清除指令:源操作数 与 第2操作数反码 进行“与”操作

1
2
BICS R0, R2, #0x80000000
;清除R2中的位31,其余的位保持不变,刷新标志位。

比较与测试指令:

根据其结果更新条件码标志(结果丢弃)

  • 比较指令 CMP:目的操作数 - 源操作数

  • 取反比较指令 CMN:目的操作数 + 源操作数

  • 位测试指令 TST:两操作数进行 “与” 操作,等价于 ANDS

  • 测试相等 TEQ:两操作数进行 “异或” 操作,等价于 TEQ

乘加指令:

1
MLA R0, R1, R2, R3 ;R0 <- R1*R2+R3

C语言程序 调用 汇编语言程序

ATPCS——统一的函数过程调用标准,定义了寄存器组中的 R0R1R2R3 作为参数传递和结果返回寄存器,若参数数目 > 4 个,则使用堆栈进行传递。

⭐️要点:C语言程序需要使用 extern 关键字声明汇编程序

1
2
3
4
5
6
extern void strcopy(char* d, const char* s); //extern声明该汇编语言程序
int main(void){
const char src = "Source";
char dest[10];
strcopy(dest, src);
}
1
2
3
4
5
6
7
8
9
AREA StrCopy CODE, READONLY
EXPORT strcopy ;EXPORT伪操作声明 本程序可被其他程序调用
strcopy
LDRB R2, [R1], #1 ;R1存放src字符串地址
STRB R2, [R0], #1 ;R0存放dest字符串地址
CMP R2, #0
BNE strcopy
MOV PC, LR ;从子程序中返回
END

C语言程序 嵌入 汇编语言程序

使用内嵌汇编时,用户无需保存和恢复寄存器。

此外,一般不要直接指定物理寄存器,而让编译器进行分配。

1
2
3
4
5
6
7
8
9
10
11
void strcopy(char* src, const char* dst){
int ch;
__asm
{
myloop:
LDRB ch, [src], #1
STRB ch, [dst], #1
CMP ch, #0
BNE myloop
}
}

汇编语言程序调用 C语言程序

⭐️要点:汇编语言程序中使用 IMPORT 伪操作来声明C语言程序,并通过 BL 指令来调用子程序

计算i+2i+3i+4i+5ii + 2i + 3i + 4i + 5i

1
2
3
int fun(int a, int b, int c, int d, int e){
return a + b + c + d + e;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
EXPORT f
AREA f,CODE,READONLY
IMPORT fun
STR LR, [SP, #-4]! ;预先保存LR
ADD R1, R0, R0
ADD R2, R1, R0
ADD R3, R1, R2
STR R3, [SP, #-4]!
ADD R3, R1, R1
BL fun
ADD SP, SP, #4
LDR PC, [SP], #4
END