ARM-指令集全解析:从基础到高阶应用

一、ARM 指令集体系结构版本

ARM 公司定义了多个指令集版本:

  • ARMv1:原型机 ARM1,没有用于商业产品。

  • ARMv2:扩展 V1,包含 32 位乘法指令和协处理器指令。

  • ARMv3:第一个微处理器 ARM6 核心,支持 Cache、MMU、写缓冲。

  • ARMv4:应用最广泛的 ARM 指令集版本。

    • ARM7TDMI、ARM720T、ARM9TDMI、ARM940T、ARM920T、StrongARM。

  • ARMv5

    • ARM9E-S、ARM966E-S、ARM1020E、ARM1022E、XScale → 基于 ARMv5TE。

    • ARM9EJ-S、ARM926EJ-S、ARM7EJ-S、ARM1026EJ-S → 基于 ARMv5EJ。

    • ARM10 也采用。

    • 后缀含义:

      • E:增强型 DSP 指令集,算法和 16 位乘法操作。

      • J:支持 Java。

  • ARMv6

    • ARM11 系列。

    • ARM1136J(F)-S:SIMD、Thumb、Jazelle、DBX、VFP、MMU。

    • ARM1156T2(F)-S:SIMD、Thumb-2、VFP、MPU。

    • ARM1176JZ(F)-S:增加 MMU、TrustZone。

    • ARM11 MPCore:支持 1~4 核 SMP、MMU。

  • ARMv7-A:Cortex A7 等。

二、常用指令

1. MOV 指令

  • 加载立即数到寄存器或寄存器值传递。
mov r0, #2   ; 加载立即数 2 到寄存器 r0
mov r1, r0   ; 将 r0 的值加载到 r1

2. ADD / SUB 指令

ADD Rd, Rn, #const
ADD Rd, Rn, Rm, <shift>SUB Rd, Rn, #const
SUB Rd, Rn, Rm, <shift>

3. 移位操作

  • LSL:逻辑左移

  • LSR:逻辑右移

  • ASR:算术右移(保持符号位)

  • ROR:循环右移

  • RRX:带进位右移 1 位

移位可由立即数或寄存器指定,影响进位标志 C。

4. 立即数定义(imm12)

ARM 指令中的立即数并非任意 32 位数,而是 12 位立即数 (imm12),由以下规则决定:

  • 条件 1:数值范围在 0~0xFF 之间时一定是立即数。

  • 条件 2:把数写成二进制后,从最高位 1 到最低位 1 之间的位数 ≤ 8 位。

  • 条件 3:补足 8 位后,右边必须是偶数个连续的 0。

实际上 ARM 将 imm12 编码为:

  • 8 位常数 (0~255) + 4 位循环右移位数 (0~15)
  • 旋转步长是 2,即可表示 0~30 偶数位的右移。

示例:

  • 0x234 = 0000 0010 0011 0100 → 符合条件,是立即数。

  • 0x3F4 = 0000 0011 1111 0100 → 符合条件,是立即数。

  • 0x132 = 0000 0001 0011 0010 → 末尾只有 1 个 0,不符合条件。

  • 0x7F8 = 0000 0111 1111 1000 → 末尾 3 个 0,不满足条件。

  • 0xFAB4 = 1111 1010 1011 0100 → 位宽超过 8 位,不是立即数。

5. LDR / STR 指令

  • 加载和存储数据:
ldr r0, =0x2FAB4            ; 常量加载
ldr r0, [r1, #4]            ; 偏移寻址
ldr r0, [r1], #8            ; 读后更新基址
ldr r0, [r1, #8]!           ; 先更新基址再读str r0, [r1, #4]            ; 存储数据
  • 多寄存器操作:
ldmia r0!, {r1-r4}          ; 从内存加载多个寄存器
stmfd sp!, {r0-r12, lr}     ; 保存现场

6. BIC / ORR 指令

bic Rd, Rn, #const   ; 清零
orr Rd, Rn, #const   ; 置位

7. CMP 指令

  • 比较两个数,更新标志位。
mov r0, #100
cmp r0, #100   ; Z=1 → 相等

8. 条件执行与条件码

指令可带条件码执行:

  • EQ:等于 (Z=1)

  • NE:不等于 (Z=0)

  • CS/HS:无符号大于等于 (C=1)

  • CC/LO:无符号小于 (C=0)

  • MI:负数 (N=1)

  • PL:正数 (N=0)

  • VS:溢出 (V=1)

  • VC:无溢出 (V=0)

  • HI:无符号大于 (C=1, Z=0)

  • LS:无符号小于等于 (C=0 或 Z=1)

  • GE:有符号大于等于 (N=V)

  • LT:有符号小于 (N≠V)

  • GT:有符号大于 (Z=0, N=V)

  • LE:有符号小于等于 (Z=1 或 N≠V)

  • AL:无条件执行

示例:

movcs r0, #100   ; 仅 C=1 时执行

9. B / BL / BX跳转指令

指令功能描述PC 的变化LR 的变化跳转目标常见用途
B无条件跳转(类似 gotoPC ← PC + 偏移量(立即数)不变立即数偏移(label 地址)循环、分支、跳转到异常处理
BL跳转并保存返回地址(函数调用)PC ← PC + 偏移量(立即数)LR ← 调用点下一条指令的地址立即数偏移(label 地址)子程序调用(函数调用)
BX跳转到寄存器地址PC ← 指定寄存器的值不变任意寄存器(如 LR、R0)子程序返回(常见 bx lr

三、栈操作

  • ARM 采用 满减栈 (Full Descending)

入栈

stmfd sp!, {r0, r1, r2, r3-r12, lr}

出栈

ldmfd sp!, {r0, r1, r2, r3-r12, lr}

栈的实现方式

  • 空增:先写入数据,再自增

  • 空减:先写入数据,再自减

  • 满增:先自增,再写入数据

  • 满减:先自减,再写入数据(ARM 采用)

类型含义压栈操作出栈操作SP 指向
满减栈 (Full Descending, FD)栈向低地址增长,SP 指向已用单元先递减 SP → 写数据读数据 → 递增 SP已用单元
满增栈 (Full Ascending, FA)栈向高地址增长,SP 指向已用单元先递增 SP → 写数据读数据 → 递减 SP已用单元
空减栈 (Empty Descending, ED)栈向低地址增长,SP 指向空单元写数据 → 递减 SP递增 SP → 读数据空单元
空增栈 (Empty Ascending, EA)栈向高地址增长,SP 指向空单元写数据 → 递增 SP递减 SP → 读数据空单元

四、函数与参数传递

汇编调用 C

import func_c
bl func_c

C 调用汇编

extern void func_asm(void);
func_asm();

参数传递规则

  • 前 4 个参数 → r0 ~ r3

  • 返回值 → r0

  • 超过 4 个参数 → 栈传递

函数嵌套与现场保护

  • LR 会保存返回地址,但函数嵌套时 LR 会被覆盖。

  • 解决方法:调用前使用栈保存 LR 和相关寄存器,返回时恢复。

五、模式切换与 CPSR

CPSR(Current Program Status Register)低 5 位决定工作模式:

  • User、FIQ、IRQ、Supervisor、Abort、Undefined、System

指令

mrs r0, cpsr        ; 读 CPSR
msr cpsr_c, r0      ; 写 CPSR

常见操作:

  • 切换工作模式:修改低 5 位

  • 开关中断:修改 I、F 位

六、ROM 类型分类

类型是否可编程是否可擦除擦除方式擦写次数应用场景
Mask ROM制造时固化不可擦写大批量固定程序
PROM一次一次性小批量定制程序
EPROM紫外线少量(几十次)开发测试
EEPROM电擦除(字节级)10^5 ~ 10^6BIOS、配置数据
Flash ROM电擦除(块/扇区)10^4 ~ 10^5SSD、U盘、嵌入式系统

Flash ROM 分类总结表

类型访问方式读取速度写入/擦除速度容量范围成本常见应用
NOR Flash随机访问(字节级/字寻址)MB ~ 数百 MB固件、Bootloader、系统代码存储
NAND Flash页/块访问较慢GB 级U 盘、SSD、SD 卡、大容量数据存储

七、基本代码实现

ARM汇编语言

	area reset, readonly, codepreserve8code32entry;ldr r0, =0x40000000;ldr r1, =0x3456781A;str r1, [r0, #4] ;*(r0 + 1) = r1	 ;str r1, [r0], #4   ;*r0++ = r1;str r1, [r0, #4]! ;*++r0 = r1;ldr r0, =0x40000000;ldr r3, [r0];ldr r0, = 0x40000004;ldr r4, [r0];add r5, r3, r4;ldr r0, =0x40000008;str r5, [r0];mov r0, #0;orr r0, r0, #(1 << 7)	  ;0000 0000 0000 0000 0000 0000 1000 0000;ldr r0, =0x7FFFFFFF	;adds r0, r0, #1;mov r0, #3;mov r1, #5;mov r2, #4;cmp r0, r1;movls r3, r1;movge r3, r0;cmp r3, r2;movls r3, r2;b lable	  ;branch;mov r0, #3;mov r1, #5
;lable
;	mov r0, #5
;	mov r1, #3	
;	mov r2, #4
;	cmp r0, r1
;	bls less
;	bgt great
;great	
;	mov r3, r0
;	b  lable
;less
;	mov r3, r1	  ;lable
;	cmp r3, r2
;	bgt finished
;	mov r3, r2    
; 	mov r0, #1		;i
;	mov r1, #0		;sum;loop	
;	cmp r0, #100
;	bgt finished
;	add r1, r1, r0
;	add r0, r0, #1
;	b loopldr pc, =_start_asm_maxstmfd sp!, {r0-r12, lr}bl _asm_minldmfd sp!, {r0-r12, lr} cmp r0, r1movge r2, r0movlt r2, r1bx lrexport _asm_min
_asm_mincmp r0, r1movle r2, r0movgt r2, r1mov r0, r2bx lr		_startldr sp, =0x40001000mrs r0, cpsr;xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxx0 0000bic r0, r0, #0x1Forr r0, r0, #0x10 ;0001 0000msr	cpsr_c, r0ldr sp, =0x40001000sub sp, sp, #1024import mainb main;stmfd sp!, {r0-r12, lr};import c_max;mov r0, #2;mov r1, #3;bl c_max;ldmfd sp!, {r0-r12, lr};mov r0, #11;mov r1, #22finishedb finished	end

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/96457.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/96457.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第3讲 机器学习入门指南

近年来&#xff0c;随着企业和个人生成的数据量呈指数级增长&#xff0c;机器学习已成为日益重要的技术领域。从自动驾驶汽车到流媒体平台的个性化推荐&#xff0c;机器学习算法已广泛应用于各个场景。让我们深入解析机器学习的核心要义。3.1 机器学习定义机器学习是人工智能的…

深入理解跳表:多层索引加速查找的经典实现

跳表&#xff08;Skip List&#xff09;是一种多层有序链表结构&#xff0c;通过引入多级索引加速查找&#xff0c;其核心设计类似于“立体高速公路系统”&#xff0c;底层是原始链表&#xff0c;上面有各种高度的"高架桥"。 高层道路跨度大&#xff0c;连接远方节点…

Flutter 视频播放器——flick_video_player 介绍与使用

在移动端应用中&#xff0c;视频播放是一个常见的功能场景&#xff0c;例如短视频、直播、课程、广告展示等。 Flutter 本身并没有直接提供视频播放器组件&#xff0c;而是依赖第三方库来实现。 今天要介绍的库是 flick_video_player&#xff0c;它基于 video_player 封装&…

编写cmakelists文件常用语句

cmake_minimum_required (VERSION 3.10) 指定最小版本project(XXXX) 指定项目名字 ---------------set(MAIN_EXEC_NAME dwarf_parser) 定义变量${ MAIN_EXEC_NAME } 变量取值set(CMAKE_CXX_STANDARD 14) 指定c14标准&#xff0c;还有11、17、20等标准…

麒麟桌面系统找不到mbr启动,并重新安装grub

根据你提供的情况,“麒麟桌面系统找不到MBR启动”,这通常是由于GRUB引导损坏、MBR记录丢失或分区表异常导致的。你可以按照以下步骤重新安装GRUB并修复MBR启动: ✅ 步骤一:准备工具 使用银河麒麟LiveCD或U盘启动盘(可用Ventoy制作); 启动电脑,选择从U盘或光盘进入Live环…

【音频字幕】构建一个离线视频字幕生成系统:使用 WhisperX 和 Faster-Whisper 的 Python 实现

一、背景介绍 对于一端没有字幕外国视频、字幕&#xff0c;在不懂外语的情况下&#xff0c;怎么获取相关内容&#xff1f;作为技术宅&#xff0c;怎么自建搭建一个语音转文字的环境当前AI技术这么发达&#xff1f; 试试 二、系统设计 音频提取(仅仅是视频需要该逻辑、本身就是音…

Linux ALSA架构:PCM_OPEN流程 (二)

一 应用端源码路径: external\tinyalsa\pcm.c external\tinyalsa\pcm_hw.cstruct pcm *pcm_open(unsigned int card, unsigned int device,unsigned int flags, struct pcm_config *config) {...pcm->ops &hw_ops;pcm->fd pcm->ops->open(card, device,…

tp5的tbmember表闭包查询 openid=‘abc‘ 并且(wx_unionid=null或者wx_unionid=‘‘)

闭包查询 tbmember表闭包查询查询 openid‘abc并且islose0并且islogout0并且&#xff08;wx_unionidnull或者wx_unionid’&#xff09; Db::table(tbmember)->where([openid>abc,islose>0,islogout>0])->where(function ($query){$query->where(wx_unioni…

邪修实战系列(3)

1、第一阶段邪修实战总览&#xff08;9.1-9.30&#xff09; 把第一阶段&#xff08;基础夯实期&#xff09;的学习计划拆解成极具操作性的每日行动方案。这个计划充分利用我“在职学习”的特殊优势&#xff0c;强调“用输出倒逼输入”&#xff0c;确保每一分钟的学习都直接服务…

【GD32】ROM Bootloader、自定义Bootloader区别

Bootloader是应用程序跑起来之前&#xff0c;用于初始化的一段程序&#xff0c;它分为两种&#xff0c;ROM Bootloader、自定义Bootloader。GD32芯片出厂时预烧录在ROM中的Bootloader&#xff08;以下简称ROM Bootloader&#xff09;和自己编写的Bootloader&#xff08;以下简称…

Linux防火墙-Firewalld

一、 概述 按表现形式划分&#xff1a; 软件防火墙&#xff1a; 集成在系统内部&#xff0c;Linux系统&#xff1a; iptables、firewalld、ufw&#xff1b; windows系统下&#xff1a; windows defender 硬件防火墙&#xff1a; 华为防火墙、思科防火墙、奇安信防火墙、深信服防…

【Qt】PyQt、原生QT、PySide6三者的多方面比较

目录 引言 一、基本定义 二、核心对比维度 1. 编程语言与开发效率 2. 功能与 API 兼容性 3. 性能表现 4. 许可证与商业使用 5. 社区与文档支持 三、迁移与兼容性 四、适用场景推荐 五、总结对比表 总结 引言 PySide6、PyQt&#xff08;通常指 PyQt5/PyQt6&#xf…

JavaWeb站内信系统 - 技术设计文档

1. 系统概述1.1 项目背景本系统旨在为企业或社区平台提供一套完整的站内信解决方案&#xff0c;支持用户之间的消息发送、接收、管理等功能&#xff0c;提升用户间的沟通效率。1.2 设计目标实现用户间消息发送和接收支持一对一和一对多消息发送提供消息状态跟踪&#xff08;已读…

Java基础 9.10

1.System类常见方法和案例exit&#xff1a;退出当前程序arraycopy&#xff1a;复制数组元素&#xff0c;比较适合底层调用&#xff0c;一般使用 Arrays.copyOf 完成复制数组int[] src{1,2,3};int[] dest new int[3]; System.arraycopy(src, 0, dest, 0, 3);currentTimeMilens&…

详解flink性能优化

1. 简介 Apache Flink是一个强大的流处理框架&#xff0c;其性能很大程度上取决于内存的使用效率。在大规模数据处理场景中&#xff0c;合理的内存配置和优化可以显著提升Flink作业的性能和稳定性。本文将深入探讨Flink内存优化的各个方面&#xff0c;包括状态后端选择、内存配…

VueFlow的箭头怎么调整

正好最近用到了VueFlow组件&#xff0c;发现箭头默认样式太小&#xff0c;无法体现流程展示&#xff0c;因此翻阅相关资料得出下列方法&#xff0c;有什么更好的方法&#xff0c;大家可以推荐推荐&#xff0c;谢谢。方法1&#xff1a;通过边&#xff08;Edge&#xff09;的样式…

【Python】S1 基础篇 P9 文件处理与异常处理技术

目录文件读取操作读取文件的全部内容相对路径和绝对路径逐行访问文件内容文件写入操作写入单行内容写入多行内容结构化数据的存储异常处理机制理解异常的工作原理ZeroDivisionError异常示例try-except语句块的使用else语句块的正确使用静默失败的合理应用本文将深入探讨Python中…

分布式事务实战手册:从四场业务灾难看方案选型与落地陷阱

在分布式系统的稳定性战役中&#xff0c;数据一致性问题如同潜伏的暗礁。某生鲜电商因分布式事务设计缺陷&#xff0c;在春节促销期间出现"下单成功但无库存发货"的悖论&#xff0c;3小时内产生2300笔无效订单&#xff0c;客服投诉量激增300%&#xff1b;某银行转账系…

Java算法题中的输入输出流

在Java算法题中&#xff0c;处理输入输出主要依赖系统流&#xff08;System.in和System.out&#xff09;&#xff0c;常用的方法总结如下&#xff1a; 一、输入方法&#xff08;读取系统输入&#xff09; 主要通过java.util.Scanner类或BufferedReader类实现&#xff0c;适用于…

墨水屏程序

EPD Reader 基于ESP32-C3的电子墨水屏阅读器&#xff0c;支持ap 配网、sntp 时间同步、txt阅读、天气预报、显示节假日信息、农历显示、自动休眠、web配置等功能。这是在另一个项目 一个rust embassy esp32c3 的练习项目-CSDN博客的基础上修改的 。 界面比较粗糙&#xff0c;以…