淮北市网站建设_网站建设公司_响应式开发_seo优化
2026/1/7 8:32:55 网站建设 项目流程

ARM 汇编指令:LSL(逻辑左移) 和 LSR(逻辑右移)

本文来自于我关于 ARM 汇编指令系列文章。欢迎阅读、点评与交流~
1、汇编指令在不同架构中的联系与区别
2、ARM 汇编指令:MOV
3、ARM 汇编指令:LDR
4、ARM 汇编指令:STR
5、ARM 汇编指令:MRS 和 MSR
6、ARM 汇编指令:ORRS
7、ARM 汇编指令:BEQ
8、ARM 汇编指令:TST
9、ARM 汇编指令:B
10、ARM 汇编指令:BX
11、ARM 汇编指令:ERET
12、ARM 汇编指令:STP\LDP
13、ARM 汇编指令:UBFX
14、ARM 汇编指令:STM
15、ARM 汇编指令:LDM
16、ARM 汇编指令:LSL(逻辑左移) 和 LSR(逻辑右移)
17、ARM 汇编指令:ROR(循环右移)

LSLLSR是 ARM 汇编中两个最基础且重要的移位指令。

核心概念:移位操作

在了解具体指令前,首先要明白移位是什么。想象一个二进制数,比如8的 8 位二进制表示是00001000

  • 左移就是将所有位向左移动,空出的低位补 0。00001000左移 1 位变成00010000(即 16)。左移一位通常相当于乘以 2
  • 逻辑右移就是将所有位向右移动,空出的高位补 0。00001000右移 1 位变成00000100(即 4)。逻辑右移一位通常相当于除以 2(向零取整)

在 ARM 中,移位操作不仅可以单独使用,还能与大多数数据处理指令(如ADD,MOV,CMP等)免费结合,这是 ARM 指令集一个非常强大和灵活的特性。但我们先看作为独立指令的LSLLSR


1. LSL - 逻辑左移

功能:将寄存器中的二进制位向左移动指定的位数,右侧空出的低位用 0 填充。
本质:相当于无符号乘法(乘以 2^n)。

语法

LSL{S} <Rd>, <Rm>, <Rs> ; 用寄存器 Rs 的值指定移位位数 LSL{S} <Rd>, <Rm>, #<imm5> ; 用立即数 imm5 (0-31) 指定移位位数
  • {S}:可选的条件标志更新后缀。如果加上S,则根据移位结果更新CPSR中的N(负标志)和Z(零标志)。移位操作也会影响C(进位标志)。
  • <Rd>:目标寄存器。
  • <Rm>:源操作数寄存器。
  • <Rs>:存放移位位数的寄存器(通常只使用低 8 位)。
  • #<imm5>:5 位立即数移位量(0-31)。

工作原理

Before: Rm = [b31 b30 ... b1 b0] After: Rd = [b31-n ... b0 0 ... 0] <-- n 个 0 填入低位 \___________/ 向左移动 n 位

最后移出的那一位(原b31-n+1位)会进入CPSRC(进位)标志。

示例

MOV R1, #5 ; R1 = 5 (二进制 00000101) LSL R0, R1, #2 ; R0 = R1 << 2 ; 计算过程: 00000101 << 2 = 00010100 ; 结果: R0 = 20 (5 * 4)
MOVS R2, #0x80000001 ; R2 = 0x80000001,设置标志 LSLS R3, R2, #1 ; R3 = R2 << 1,并更新标志 ; 计算过程: 1000...0001 << 1 = 0000...0010 ; 结果: R3 = 0x00000002 ; 标志变化:最后移出的 '1' 进入 C 标志,所以 C = 1。结果非零,所以 Z = 0。

2. LSR - 逻辑右移

功能:将寄存器中的二进制位向右移动指定的位数,左侧空出的高位用 0 填充。
本质:相当于无符号除法(除以 2^n)。

语法

LSR{S} <Rd>, <Rm>, <Rs> ; 用寄存器 Rs 的值指定移位位数 LSR{S} <Rd>, <Rm>, #<imm5> ; 用立即数 imm5 (1-32) 指定移位位数

注意:立即数移位范围是1-32。当#imm5为 32 时,结果为 0,且最后移出的位进入C标志。

工作原理

Before: Rm = [b31 b30 ... b1 b0] After: Rd = [0 ... 0 b31 ... bn] <-- n 个 0 填入高位 \___________/ 向右移动 n 位

最后移出的那一位(原bn-1位)会进入CPSRC(进位)标志。

示例

MOV R1, #20 ; R1 = 20 (二进制 00010100) LSR R0, R1, #2 ; R0 = R1 >> 2 ; 计算过程: 00010100 >> 2 = 00000101 ; 结果: R0 = 5 (20 / 4)
MOV R2, #0x80000001 ; R2 = 0x80000001 LSRS R3, R2, #1 ; R3 = R2 >> 1,并更新标志 ; 计算过程: 1000...0001 >> 1 = 0100...0000 ; 结果: R3 = 0x40000000 ; 标志变化:最后移出的 '1' 进入 C 标志,所以 C = 1。结果非负非零,所以 N=0, Z=0。

关键点与进阶用法

  1. 移位量为 0:对于LSL #0,操作数不变,但可能影响C标志(C标志会被设置为ALU的进位输出,在移位量为0的特定情况下,其行为有详细规定,通常编程时可忽略此边界情况)。对于LSR #0,在 ARM 中实际表示LSR #32,这是一个特例。

  2. 桶形移位器:ARM 处理器有一个称为“桶形移位器”的硬件单元,这使得移位操作可以在一个时钟周期内完成,并且可以与其他指令结合而无额外开销。这是 ARM 指令集高效的关键之一。

  3. 与其他指令结合(灵活的第二操作数)
    这是 ARM 汇编最常用的特性之一。几乎所有的数据处理指令(ADD,SUB,MOV,CMP,AND,ORR等)的第二个操作数都可以先进行移位,然后再参与运算。

    ADD R0, R1, R2, LSL #2 ; R0 = R1 + (R2 * 4) CMP R3, R4, LSR #3 ; 比较 R3 和 (R4 / 8) MOV R5, R6, ROR #4 ; R5 = 将 R6 循环右移 4 位后的值 (ROR是另一种移位)

    这种结合极大地增强了指令的表达能力,一条指令完成了“移位+运算”。

  4. 与算术右移 ASR 的区别

    • LSR是逻辑右移,高位补0。用于处理无符号数
    • ASR(算术右移)高位用原最高位(符号位)填充。用于保持有符号数的符号,相当于有符号除法。

总结

指令全称方向填充值主要数学意义典型用途
LSLLogical Shift Left向左低位补 0乘以 2^n快速乘法、位组装、掩码生成
LSRLogical Shift Right向右高位补 0无符号除以 2^n快速无符号除法、位提取、无符号数处理

掌握LSLLSR是理解 ARM 高效编程和位操作的基础。务必通过实践来熟悉它们的行为,尤其是与条件标志和与其他指令结合使用的方式。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询