ARM 汇编指令:STR

ARM 汇编指令:STR

1. 核心定义

STRStore Register 的缩写,意思是 将寄存器中的值存储(写入)到内存。它是 ARM 汇编中最基本、最常用的内存写入指令。

与它对应的是 LDR 指令,后者是从内存加载数据到寄存器。

2. 基本语法

assembly 复制代码
STR{<size>} <Rt>, [<Rn>, <operand2>]
  • {<size>} : 可选 的后缀,指定操作的数据大小。默认为 32 位(字)。
    • B - 字节 (8位),如 STRB
    • H - 半字 (16位),如 STRH
    • 无后缀 - 字 (32位),如 STR
    • 在 ARMv8 (AArch64) 中,还可以使用 W (32位) 或 X (64位) 寄存器来隐含大小。
  • <Rt> : 源寄存器,其值将被存储到内存。
  • [<Rn>, <operand2>] : 内存地址表达式。
    • Rn: 基址寄存器,存放内存地址的基值。
    • operand2: 地址偏移量,可以是立即数或另一个寄存器,有时还可以带移位。

3. 寻址模式(关键部分)

寻址模式决定了如何计算最终的内存地址。

a) 偏移模式

地址是基址寄存器加上一个偏移量。原基址寄存器的值不变

assembly 复制代码
STR  R1, [R2, #12]   ; 内存地址 = R2 + 12,将 R1 的值存入此地址。R2 本身的值不变。

b) 前变址模式

先计算新地址 (基址+偏移),然后使用这个新地址进行存储。基址寄存器的值会被更新为这个新地址

assembly 复制代码
STR  R1, [R2, #12]!  ; 注意感叹号 '!'
; 1. 计算新地址: R2_new = R2_old + 12
; 2. 将 R1 的值存储到 [R2_new] 指向的内存
; 3. 将 R2 寄存器的值更新为 R2_new

c) 后变址模式

先使用原基址寄存器的值作为地址 进行存储,然后再更新基址寄存器(加上偏移量)。

assembly 复制代码
STR  R1, [R2], #12   ; 偏移量写在括号外
; 1. 将 R1 的值存储到 [R2_old] 指向的内存
; 2. 更新 R2: R2_new = R2_old + 12

这种模式非常适合在存储后移动指针,例如遍历数组。

d) 寄存器偏移

偏移量可以来自另一个寄存器,并可选择移位操作。

assembly 复制代码
STR  R1, [R2, R3]         ; 地址 = R2 + R3
STR  R1, [R2, R3, LSL #2] ; 地址 = R2 + (R3 * 4)

4. 数据大小示例 (ARMv7/AArch32)

assembly 复制代码
STR    R0, [R1]       ; 将 R0 中的 32 位字(Word)存储到 R1 指向的地址
STRB   R0, [R1]       ; 只将 R0 的最低 8 位字节(Byte)存储到内存
STRH   R0, [R1]       ; 只将 R0 的最低 16 位半字(Halfword)存储到内存

5. AArch64 (ARMv8 64位) 中的变化

在 64 位架构下,语法和寄存器名称有更新:

  • 通用寄存器是 X0-X30 (64位) 或 W0-W30 (32位)。
  • STR 的数据大小通常由寄存器宽度隐含,但也可用后缀指定。
  • 偏移量范围通常更大。
assembly 复制代码
STR   X0, [X1, #8]    ; 将 64 位的 X0 存储到地址 X1+8
STR   W0, [X1, #4]    ; 将 32 位的 W0 存储到地址 X1+4
STRB  W0, [X1]        ; 将 W0 的低 8 位存储到地址 X1

6. 一个简单完整的示例

假设我们要将数组 array 的第一个元素(在内存中)设置为 100。

assembly 复制代码
.data
array: .word 0, 0, 0, 0   ; 定义一个包含4个字的数组,初始为0

.text
.global main
main:
    // 假设我们要将 array[0] 赋值为 100
    LDR   R0, =array       ; R0 获得数组的首地址(加载地址)
    MOV   R1, #100         ; R1 = 100,这是我们要存储的值
    STR   R1, [R0]         ; 关键指令:将 R1 的值(100)存储到 R0 指向的内存地址

    // 使用后变址模式存储 200 到 array[1]
    MOV   R1, #200
    STR   R1, [R0], #4     ; 存储到 [R0],然后 R0 = R0 + 4(指向下一个字)

    // 此时 R0 指向 array[1] 的地址
    BX    LR               ; 返回

7. 要点总结

特性 说明
目的 将寄存器数据写入内存
对应指令 LDR(从内存读)
关键语法 STR Rt, [Rn, #offset]
寻址模式 偏移 (基址不变)、前变址 (先算地址并更新基址)、后变址(先存后更新基址)
数据大小 STR(字,32位),STRH(半字,16位),STRB(字节,8位)
应用场景 变量赋值、保存寄存器到栈(函数调用)、向内存填充数据、数据结构操作等

理解 STR 及其寻址模式是掌握 ARM 汇编内存操作的基础。它与 LDR 指令一起,构成了寄存器和内存之间数据交换的核心手段。

相关推荐
比奇堡派星星1 天前
Linux 杂项设备驱动框架详解
linux·arm开发·驱动开发
xingzhemengyou11 天前
LINUX 通过/proc/interrupts了解系统硬件中断的使用情况
linux·arm开发
rfidunion1 天前
ubuntu下使用qemu模拟ARM(一)-------安装samba服务器
服务器·arm开发·ubuntu
三佛科技-134163842121 天前
FT32F072xx、FT32F072xB、FT32F072x6/x8基于ARM Cortex-M0内核32位单片机分析
arm开发·单片机·嵌入式硬件·智能家居·pcb工艺
p66666666681 天前
STM32(基于 ARM Cortex-M 内核)中函数调用栈帧的开辟 销毁过程
arm开发·stm32·嵌入式硬件
星空真迷人2 天前
嵌入式 WiFi 加持 普通设备也能联网 “唠嗑”
arm开发·stm32·单片机·嵌入式硬件·物联网·iot
灵哎惹,凌沃敏3 天前
FreeRTOS 任务上下文切换核心函数:xPortPendSVHandler详解
c语言·arm开发
比奇堡派星星3 天前
Linux4.4使用AW9523
linux·开发语言·arm开发·驱动开发
比奇堡派星星3 天前
cmdline使用详解
linux·arm开发·驱动开发
STCNXPARM3 天前
Android14显示系统 - ARM GPU完全剖析
arm开发·arm·gpu·android显示