2025年ldr指令(ldr指令全称)

ldr指令(ldr指令全称)svg xmlns http www w3 org 2000 svg style display none svg

大家好,我是讯享网,很高兴认识大家。



 <svg xmlns="http://www.w3.org/2000/svg" style="display: none;"> <path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path> </svg> <p></p> 

讯享网

本文主要整理了arm常用的汇编指令,同时通过实例进一步讲述语句的用法。

寄存器分类介绍

1. 通用寄存器

通用寄存器是一组用于存储数据和地址的寄存器。在 ARM 架构的不同版本中,这些寄存器的数量和命名有所不同。
R0-R15 (R0-R14 + PC):
在 ARMv7 和之前的版本中,有 16 个通用寄存器,编号从 R0 到 R15。
R0 到 R14 用于存储数据和地址。
R15 通常被称为程序计数器(PC),用于存储下一条指令的地址。

X0-X30 (X0-X29 + SP):
在 ARMv8 和之后的版本中,有 31 个通用寄存器,编号从 X0 到 X30。
X0 到 X29 用于存储数据和地址。
X30 通常被称为链接寄存器(LR),用于保存返回地址。
X31 通常被称为堆栈指针(SP),用于管理堆栈。

在ARMv7架构中使用程序状态寄存器(Current Program Status Register,CPSR)来表示当前的处理器状态(processor stste),而在ARMv8里使用PSTATE寄存器来表示。

ARMv8及以后版本:

寄存器位数描述X0-X3064bit通用寄存器,如果有需要可以当作32bit使用:W0-W30FP(X29)64bit保存栈帧地址(栈底指针)LR(X30)64bit程序链接寄存器,保存子程序结束后需要执行的下一条指令SP64bit保存栈顶指针,使用SP/WSP来进行对SP寄存器的访问。PC64bit程序计数器,俗称PC指针,总是指向即将要执行的下一条指令,在arm64中,软件不能修改PC寄存器PSTATE64bit状态寄存器,用于保存处理器的当前状态信息。 在这里插入图片描述
讯享网

X0 - X7: 这8个寄存器通常用作函数参数寄存器,在函数调用时用来传递前8个参数,若参数个数大于8,就采用栈来传递。64位的函数返回值通常存放在X0寄存器中,128位的返回结果存在X0和X1两个寄存器中。
X8: 间接结果位置寄存器,用于保存子函数的返回地址。在一些情况下,X8可以用于普通的临时寄存器,用于存储中间计算结果。
X9 - X15: 通常被用作临时变量和中间计算结果的存储。调用者有责任在函数调用前保存它们的值,以免被覆盖。函数返回后,调用者也需要恢复这些寄存器的值。
X16、X17: X16 (IP0, Intra-Procedure-call scratch register 0)这个寄存器通常被用作临时寄存器,用于存储函数内部的中间计算结果。它在函数调用过程中可能会被修改,所以调用者需要自行保存和恢复。X17与X16类似。

X29: Frame Pointer (FP) 寄存器,它的主要作用是指向当前函数的栈帧(Stack Frame),方便访问函数内部的局部变量和参数。当一个函数被调用时,x29 寄存器会被设置为指向该函数的栈帧起始地址。这样可以通过 x29 寄存器轻松访问函数内部的局部变量和参数,而不需要依赖 x30 寄存器(Link Register)中存储的返回地址。

X30: Link Register (LR),它的主要作用是在函数调用时存储函数的返回地址,以便函数执行完毕后能够正确地返回到调用点。当一个函数被调用时,CPU 会将当前执行点的地址保存到 x30 寄存器中。这样在函数执行完毕后,只需要从 x30 寄存器中恢复返回地址,就可以正确地返回到调用点。注意:当一个函数被调用时,CPU 会自动将当前执行点的地址(也就是函数调用语句的下一条指令地址)保存到 x30 寄存器中。

X9 - X15和X19 - X28这两组寄存器的区别:

x9 到 x15 则主要用作临时变量和中间计算结果的存储。x19 到 x28 通常用作函数的局部变量和中间计算结果的存储。对于 x9 到 x15 这些“caller-saved”寄存器,调用者(caller)有责任在函数调用前保存它们的值,并在调用后恢复。对于 x19 到 x28 这些“callee-saved”寄存器,被调用的函数(callee)有责任在返回前保存和恢复它们的值。使用“callee-saved”寄存器通常可以减少对栈的访问,提高性能。但同时也增加了函数调用时保存和恢复寄存器的开销。

ARMv8前版本:
R0-R15寄存器 根据“ARM-thumb 过程调用标准”:
R0-R3 其中,R0通常用于存储函数的返回值,R1-R3则常用于传递函数参数。在子程序调用之前,可以将R0-R3用于任何用途。被调用函数在返回之前不必恢复R0-R3。如果调用函数需要再次使用 r0-r3的内容,则它必须保留这些内容。
R4-R11 被用来存放函数的局部变量。如果被调用函数使用了这些寄存器,它在返回之前必须恢复这些寄存器的值。
R12是内部调用暂时寄存器IP。它在过程链接胶合代码(例如,交互操作胶合代码)中用于此角色。
在过程调用之间,可以将它用于任何用途。被调用函数在返回之前不必恢复R12。
R13是栈指针SP:
在ARM指令集中,R13常被用作堆栈指针,用于存储程序中的局部变量和函数调用时的返回地址。它不能用于任何其它用途。SP中存放的值在退出被调用函数时必须与进入时的值相同。用户也可以使用其他寄存器作为堆栈指针,但在Thumb指令集中,某些指令强制要求使用R13作为堆栈指针。
R14是链接寄存器LR:
用于存储函数调用之前的返回地址,如果您保存了返回地址,则可以在调用之前将R14用于其它用途,程序返回时要恢复。当执行子程序调用指令(如BL或BLX)时,R14会被设置成该子程序的返回地址。在子程序返回时,将R14的值复制回程序计数器PC即可完成子程序的调用返回。
R15是程序计数器PC:
用于存储当前正在执行的指令的地址。程序计数器是处理器控制指令执行的关键寄存器之一。它不能用于任何其它用途。由于ARM采用了流水线机制,当正确读取了PC的值后,该值为当前指令地址加8个字节,即PC指向当前指令的下两条指令地址。
注意:在中断程序中,所有的寄存器都必须保护,编译器会自动保护R4~R11。

2. 专用寄存器

CPSR是一个32位的特殊寄存器,用于存储当前程序的状态信息。它包含以下内容:

ALU状态标志 :如条件码(如零标志Z、负标志N、进位标志C等),用于反映ALU的运算结果。
中断使能位 :用于控制中断的使能状态。
执行模式位 :用于标识当前处理器的执行模式(如用户模式、系统模式、中断模式等)。

CPSR和SPSR都是程序状态寄存器,其中SPSR是用来保存中断前的CPSR中的值,以便在中断返回之后恢复处理器程序状态。
CPSR在任何处理器模式下都可被访问和修改(但某些位可能需要特权级代码才能修改)。通过读取和修改CPSR寄存器的各个标志位和控制位,可以控制程序的执行流程和处理器的行为。
备份的程序状态寄存器(SPSRs)

ARM处理器还包含5个备份的程序状态寄存器(SPSR_fiq、SPSR_irq、SPSR_svc、SPSR_abt、SPSR_und),用于在异常处理期间保存CPSR的值。当处理器进入异常模式时,会将CPSR的内容复制到对应的SPSR中;当从异常模式返回时,则可以将SPSR的内容复制回CPSR以恢复处理器的状态。

3. 控制寄存器

虽然控制寄存器不直接归类为通用或专用寄存器,但它们在ARM处理器的控制中发挥着重要作用。这些寄存器通常包含处理器的控制位和配置位,用于控制处理器的行为和工作模式。由于控制寄存器的访问和修改通常需要特权级代码,因此它们在普通的应用程序中很少被直接访问。如控制CPU的行为,如 CTRL 和 ACTLR。

2.1 32位数据操作指令

名字功能ADC带进位加法ADD加法ADDW宽加法(可以加 12 位立即数)AND按位与ASR算术右移BIC位清零(把一个数按位取反后,与另一个数逻辑与)BFC位段清零BFI位段插入CMN负向比较(把一个数和另一个数的二进制补码比较,并更新标志位)CMP比较两个数并更新标志位CLZ计算前导零的数目EOR按位异或LSL逻辑左移LSR逻辑右移MLA乘加MLS乘减MOVW把 16 位立即数放到寄存器的底16位,高16位清0MOV加载16位立即数到寄存器(其实汇编器会产生MOVW——译注)MOVT把 16 位立即数放到寄存器的高16位,低 16位不影响MVN移动一个数的补码MUL乘法ORR按位或ORN把源操作数按位取反后,再执行按位或(RBIT位反转(把一个 32 位整数先用2 进制表达,再旋转180度——译注)REV对一个32 位整数做按字节反转REVH/REV16对一个32 位整数的高低半字都执行字节反转REVSH对一个32 位整数的低半字执行字节反转,再带符号扩展成32位数ROR圆圈右移RRX带进位的逻辑右移一格(最高位用C 填充,且不影响C的值——译注)SFBX从一个32 位整数中提取任意的位段,并且带符号扩展成 32 位整数SDIV带符号除法SMLAL带符号长乘加(两个带符号的 32 位整数相乘得到 64 位的带符号积,再把积加到另一个带符号 64位整数中)SMULL带符号长乘法(两个带符号的 32 位整数相乘得到 64位的带符号积)SSAT带符号的饱和运算SBC带借位的减法SUB减法SUBW宽减法,可以减 12 位立即数SXTB字节带符号扩展到32位数TEQ测试是否相等(对两个数执行异或,更新标志但不存储结果)TST测试(对两个数执行按位与,更新标志但不存储结果)UBFX无符号位段提取UDIV无符号除法UMLAL无符号长乘加(两个无符号的 32 位整数相乘得到 64 位的无符号积,再把积加到另一个无符号 64位整数中)UMULL无符号长乘法(两个无符号的 32 位整数相乘得到 64位的无符号积)USAT无符号饱和操作(但是源操作数是带符号的——译注)UXTB字节被无符号扩展到32 位(高24位清0——译注)UXTH半字被无符号扩展到32 位(高16位清0——译注)

2.2 32位存储器数据传送指令

名字功能LDR加载字到寄存器LDRB加载字节到寄存器LDRH加载半字到寄存器LDRSH加载半字到寄存器,再带符号扩展到 32位LDM从一片连续的地址空间中加载多个字到若干寄存器LDRD从连续的地址空间加载双字(64 位整数)到2 个寄存器STR存储寄存器中的字STRB存储寄存器中的低字节STRH存储寄存器中的低半字STM存储若干寄存器中的字到一片连续的地址空间中STRD存储2 个寄存器组成的双字到连续的地址空间中PUSH把若干寄存器的值压入堆栈中POP从堆栈中弹出若干的寄存器的值

2.3 32位转移指令

名字功能B无条件转移BL转移并连接(呼叫子程序)TBB以字节为单位的查表转移。从一个字节数组中选一个8位前向跳转地址并转移TBH以半字为单位的查表转移。从一个半字数组中选一个16 位前向跳转的地址并转移

2.4 其它32位指令

名字功能LDREX加载字到寄存器,并且在内核中标明一段地址进入了互斥访问状态LDREXH加载半字到寄存器,并且在内核中标明一段地址进入了互斥访问状态LDREXB加载字节到寄存器,并且在内核中标明一段地址进入了互斥访问状态STREX检查将要写入的地址是否已进入了互斥访问状态,如果是则存储寄存器的字STREXH检查将要写入的地址是否已进入了互斥访问状态,如果是则存储寄存器的半字STREXB检查将要写入的地址是否已进入了互斥访问状态,如果是则存储寄存器的字节CLREX在本地的处理上清除互斥访问状态的标记(先前由 LDREX/LDREXH/LDREXB做的标记)MRS加载特殊功能寄存器的值到通用寄存器MSR存储通用寄存器的值到特殊功能寄存器NOP无操作SEV发送事件WFE休眠并且在发生事件时被唤醒WFI休眠并且在发生中断时被唤醒ISB指令同步隔离(与流水线和 MPU等有关——译注)DSB数据同步隔离(与流水线、MPU 和cache等有关——译注)DMB数据存储隔离(与流水线、MPU 和cache等有关——译注)DMB数据存储器隔离。DMB 指令保证: 仅当所有在它前面的存储器访问操作都执行完毕后,才提交(commit)在它后面的存储器访问操作。DSB数据同步隔离。比 DMB 严格: 仅当所有在它前面的存储器访问操作都执行完毕后,才执行在它后面的指令(亦即任何指令都要等待存储器访 问操作——译者注)ISB指令同步隔离。最严格:它会清洗流水线,以保证所有它前面的指令都执行完毕之后,才执行它后面的指令。

2.5 立即数

2.6 逻辑数

逻辑数是用来表示二值逻辑中的“是”与“否”、或称“真”与“假”两个状态的数据。在计算机中,可以用一位基2码表示逻辑数据,即8个逻辑数据可以存放在1个字节中,可用其中的每个bit(位)表示一个逻辑数据。逻辑数可以用计算机中的基2码的两个状态“1”和“0”来表示,其中“1”表示真,“0”表示假。

2.7 逻辑运算和算术运算

3.1 MRS

将状态寄存器CPSR或SPSR的内容移动到一个通用寄存器

讯享网

3.2 MSR

将立即数或通用寄存器的内容加载到CPSR或SPSR的指定字段中

 

3.3 PRIMASK

A:表示启用或禁止不精确的中止;I:表示启用或禁止IRQ中断;F:表示启用或禁止FIQ中断

3.4 FAULTMASK

讯享网

3.5 BX指令

3.6 零寄存器 wzr、xzr

因为我们在使用 str 的是没法使用立即数 0 给寄存器赋值,所以 wzr xzr就是干这个事情的。是一个比较特殊又常常见到的寄存器。

3.7 立即寻址指令

 

3.8 寄存器间接寻址指令

讯享网

3.9 寄存器移位寻址指令

 

3.10 基址寻址指令

讯享网

3.11 多寄存器寻址指令

 

3.12 无条件转移B,BAL

举例: B LABEL ; LABEL为某个位置

讯享网

BCC是指CPSR寄存器条件标志位为0时的跳转。结合CMP R3, R1,意思是比较R3 R1寄存器,当相等时跳转到环测试。因为CMP指令减去两个值并在CPSR中设置条件标志位。

3.13 条件转移

 
讯享网

3.14 WFE 和 WFI 对比

wfi 和 wfe 指令都是让ARM核进入standby睡眠模式。wfi是直到有wfi唤醒事件发生才会唤醒CPU,wfe是直到wfe唤醒事件发生,这两类事件大部分相同。唯一不同之处在于wfe可以被其他CPU上的sev指令唤醒,sec指令用于修改event寄存器的指令。

SEV
Set Event,其是否实现是可选的。如果未实现,它将作为NOP执行。如果指令作为NOP在目标上执行,汇编程序将生成诊断消息。
SEV在ARMv6T2中作为NOP指令执行。

3.15 MRC:协处理器寄存器到ARM寄存器的数据传输

MRC指令将协处理器的寄存器中数值传送到ARM处理器的寄存器中。如果协处理器不能成功地执行该操作,将产生未定义的指令异常中断。

 

3.16 MCR:寄存器到协处理器寄存器的数据传输

MCR指令将ARM处理器的寄存器中的数据传送到协处理器的寄存器中。如果协处理器不能成功地执行该操作,将产生未定义的指令异常中断。

讯享网

3.17 STM:将指令中寄存器列表中的各寄存器数值写入到连续的内存单元中

STM指令是Store Multiple的缩写,它的作用是将多个寄存器的值保存到栈中。在ARM汇编中,栈是一种后进先出 (LIFO)的数据结构,用来存储临时数据和函数调用过程中的返回地址

STM指令的语法如下:

 

其中,条件码是可选项,用来指定条件执行STM指令的条件;模式用来指定存储模式,

1、寻址模式(mode)
mode决定了基址寄存器是在执行指令前地址增减还是指令执行后增减.
I为Increment(递增)
D为Decrement (递减)
B为Before
A为After

常用的模式有IA (递增后存储) 、IB (递增前存储) 、DA (减后存储)和DB(递减前存储);SP是栈指针寄存器,用来指定栈的起始地址;寄存器列表指定要保存的寄存器。
另外四种也是寻址模式
FD 慢递减堆栈
FA 满递增堆栈
ED 空递减堆栈
EA 空递增堆栈

讯享网

在上述代码中,STMFD指令存储了RO、R1和R2的值到栈中。SP!表示栈指针寄存器递增,即存储完后栈指针自动增加,以便下一次保存操作。

2、“!”
在传输数据完成后,更新基址寄存器中的值

3、“^”

在数据传输完成后,将SPSR的值复制到CPSR中,常用于异常模式下的返回.

3.18 LDM:将数据从连续内存单元中读取到指令的寄存器列表中的各寄存器中

LDMIA

 

3.19 LDR:从内存中将一个32位的字读取到目标寄存器

讯享网

LDR指令用亍从存储器中将一个32位的字数据传送到目的寄存器中。该指令通常用于从存储器中读取32位的字数据到通用寄存器,然后对数据进行处理。当程序计数器PC作为目的寄存器时,指令从存储器中读取的字数据被当作目的地址,从而可以实现程序流程的跳转。

3.20 STR:将32位字数据写入到指定的内存单元

STR指令的格式为:

 

STR指令用亍从源寄存器中将一个32位的字数据传送到存储器中。该指令在程序设计中比较常用,寻址方式灵活多样,使用方式可参考指令LDR。

讯享网

3.21 SWI:软中断指令

SWI指令格式如下:

 

3.22 BIC清除位

讯享网

BIC指令用于清除操作数1的某些位,并把结果放置到目的寄存器中。操作数1应是一个寄存器, 操作数2可以是一个寄存器、被移位的寄存器、或一个立即数。操作数2为32位的掩码,如果在 掩码中置了某一位1,则清除这一位。未设置的掩码位保持不变。

 

3.23 EOR逻辑异或指令

讯享网

逻辑异或EOR(Exclusive OR)指令将寄存器中的值和&lt;shifter_operand&gt;的值执行按位“异或”操作,并将执行结果存储到目的寄存器中,同时根据指令的执行结果更新CPSR中相应的条件标志位。

3.24 CMN与负数对比

3.25 MVN取反

将每一位操作数都取反,若为有符号的数据则进行补码保存

 

其中上图中的0x4用二进制数(00000100)表示, 然后对其取反得到(),可见取反后为负数,因此针对负数求其补码则为储存在R0中的值,先将负数最高位转换为正数(0)取反,得到(),加1得到其补码,最后结果为(),即结果为-5;

3.26 LSL(Logical Shift Left)左移运算

用于将寄存器的值向左移位,末尾填充0。在ARM处理器中,每个寄存器都有32位,当LSL被使用时,指令将寄存器中的二进制数值向左移动指定的位数,并用0填充未使用的右侧位数。

3.27 STP

STP是一条用于将General-Purpose Registers(通用寄存器)的值存储到内存地址的指令。STP是Store Pair的缩写,用于同时将两个寄存器的值存储到连续的内存地址中。

讯享网

Rt1和Rt2是要存储的寄存器,可以是X0-X30中的任何一个。
Xn是基础地址寄存器,可以是X0-X30中的任何一个,但不能是Rt1或Rt2。
#是一个常数值,用于指定一个偏移量,范围是-2048到2047。
例如,以下是使用STP指令将X2和X3寄存器的值存储到基础地址寄存器X18指定的内存地址偏移24字节处的代码:

 

注意:结尾的!表示同时更新基础寄存器的值,即存储操作后,X18将指向下一个地址。如果不需要更新基础寄存器,可以省略!

讯享网
 

小讯
上一篇 2025-06-05 20:02
下一篇 2025-04-24 17:37

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/165687.html