2.4 ARM汇编语言程序设计
🟠 中频考点,重点是程序结构和伪指令
汇编语言程序结构
AREA MyCode, CODE, READONLY ; 定义代码段
ENTRY ; 程序入口
Start
MOV R0, #10
MOV R1, #20
ADD R2, R0, R1
; 调用子程序
BL MySubroutine
; 程序结束
MOV R0, #0x18 ; angel_SWIreason_ReportException
LDR R1, =0x20026
SWI 0x123456
MySubroutine
STMFD SP!, {R0-R12, LR} ; 压栈保护寄存器
; ... 子程序代码 ...
LDMFD SP!, {R0-R12, PC} ; 出栈并返回(PC=LR)
END ; 文件结束
常用伪指令
| 伪指令 | 功能 |
|---|---|
| AREA | 定义代码段或数据段 |
| ENTRY | 标记程序入口点 |
| END | 标记文件结束 |
| EQU | 定义常量(类似C的#define) |
| DCD | 分配并初始化32位数据 |
| DCB | 分配并初始化8位数据 |
| ALIGN | 字节对齐 |
| EXPORT | 声明全局符号(让其他文件可以引用) |
| IMPORT | 引用外部符号 |
ARM汇编与C语言混合编程
现代嵌入式开发通常用C写主要逻辑,只在需要高性能或直接操作硬件时用汇编。
在C中调用汇编函数
汇编文件(asm_func.s):
AREA FuncArea, CODE, READONLY
EXPORT MyAsmFunc ; 导出给C文件使用
MyAsmFunc
; 函数参数通过R0-R3传入
ADD R0, R0, R1 ; 返回值在R0
MOV PC, LR ; 返回
END
C文件:
在汇编中调用C函数
内嵌汇编(在C中写汇编代码)
// 使用__asm关键字
void __asm enable_irq(void) {
MRS R0, CPSR
BIC R0, R0, #0x80 // 清除I位,允许IRQ
MSR CPSR_c, R0
MOV PC, LR
}
嵌入式系统硬件基础知识
时钟与复位
了解即可
- 内部时钟:处理器内置振荡器,无需外部时钟
- 外部时钟:大多数嵌入式处理器同时支持内部和外部时钟
- nRESET引脚:前面的
n表示低电平有效(active low) - 所有基于ARM内核的芯片都有JTAG调试接口
选择题
错误说法:"大部分嵌入式处理器只能使用内部时钟,不能使用外部时钟" → 错误! 大多数处理器两种都支持。答:B
真题演练
以下是NCRE三级嵌入式真题中与本节相关的典型考题:
1. 以下对伪指令的解释错误的是( )。
- A)DCB 0x56;在内存区域分配一个字节的内存空间并初始化为0x56
- B)CODE32;伪指令通知编译器,其后的指令序列为32位的Thumb指令
- C)MyTest EQU 15000;定义一个常量MyTest值为15000,最大数为32位
- D)EXPORT伪指令用于在程序中声明一个全局的标号,该标号可在其它的文件中引用
答案解析
答:B CODE32通知编译器其后的指令序列为32位的ARM指令,而不是"32位的Thumb指令"。Thumb指令是16位的,对应的伪指令是CODE16。注意区分:CODE16 → Thumb指令(16位),CODE32 → ARM指令(32位)。
2. 在ARM汇编语言伪指令中,通过编译器在当前文件中声明要引用的一个标号main,但它不在本文件定义中,在其它源文件中定义,则本文件中使用的伪指令是( )。
- A)IMPORT main
- B)EXPORT main
- C)ENTRY main
- D)COMMON main
答案解析
答:A IMPORT用于引用在其他源文件中定义的外部标号,相当于告诉编译器"这个符号不在本文件中,去别的文件找"。EXPORT则相反,用于将本文件的标号导出,使其他文件可以引用。ENTRY标记程序入口点,COMMON不是ARM汇编标准伪指令。
3. GCC是针对Linux操作系统环境下应用程序的编译工具,下面叙述中错误的是( )。
- A)GCC将源文件生成可执行文件的过程是由:编译、汇编、连接等3个阶段组成
- B)GCC能将C语言、C++语言、汇编语言编写的源程序生成执行文件
- C)设计者若要对源程序进行调试,需要在GCC命令中加入-g参数来编译该源程序
- D)用GCC把源文件仅编译成目标文件,那么,C语言编写的应用程序中可以不要main函数
答案解析
答:A GCC从源文件生成可执行文件的过程由四个阶段组成:预处理、编译、汇编、连接。A项遗漏了预处理阶段,因此错误。B、C、D三项叙述均正确。
4. 【填空题】由于Bootloader的实现依赖于CPU的体系结构,因此大多数Bootloader都分为stage1和stage2两大部分。依赖于CPU体系结构的代码,比如设备初始化代码等,通常都放在stage1中,且使用_语言来实现。而stage2则通常用C语言来实现,这样代码会具有更好的可读性和_性。
答案
答:汇编;可移植 Bootloader的stage1使用汇编语言编写,因为需要直接操作硬件且追求精简高效(短小精悍)。stage2用C语言编写,因为C语言具有更好的可读性和可移植性,便于实现更复杂的功能。
5. 【填空题】GNU开发工具套件中的C语言编译器,其英文简称是_。针对于ARM体系结构的目标机而言,其Linux环境下的C语言编译器命令书写格式中,其带前缀的命令是_。
答案
答:GCC;arm_linux_gcc GCC(GNU Compiler Collection)是GNU开发工具套件中的核心编译工具。当目标机为ARM体系结构时,交叉编译器的命令格式带有平台前缀,即arm_linux_gcc。
章节测验
进入 第二章测验 检验学习效果。