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 天前
汇编 位运算 (逆向分析)
汇编·逆向·位运算·asm·windows编程·二进制逆向
浩浩测试一下1 天前
汇编 高低八位寄存器数据存储方式(逆向分析)
汇编·网络安全·逆向·二进制·免杀·寄存器·windows编程
Emtronix英创1 天前
RK3568 CAN驱动测试及使用说明
linux·arm开发·rk3568·全国产主板
a83331962 天前
C语言嵌入汇编详解
汇编·单片机·语言
yoyo_zzm2 天前
汇编到PHP:五大编程语言核心特性全解析
开发语言·汇编·php
时空自由民.3 天前
Arm Coretex-M核MCU做IAP/OTA升级时候为什么要做中断向量表地址偏移?
arm开发·单片机·嵌入式硬件
黑猫学长呀3 天前
存储宝典第1篇:Nand SCA是什么
arm开发·arm·nand·存储芯片·nandflash·onfi
Freak嵌入式3 天前
WIZnet-EVB-Pico2开始,用MicroPython玩转以太网开发
arm开发·人工智能·python·嵌入式硬件·机器人·嵌入式·micropython
振南的单片机世界3 天前
推挽输出:上管推、下管拉,驱动强但不“合群”
arm开发·stm32·单片机·嵌入式硬件
ComputerInBook4 天前
X64 汇编 MOVSD 的两种用法
汇编·汇编指令·movsd