ARM指令集—SWP指令

ARM指令集—SWP指令


SWP和SWPB是ARM指令集中对存储单元的原子操作,即对存储单元的一次读和一次不可被分割。SWP和SWPB分别完成存储器和寄存器之间 一个字(32bit)和一个字节(8bit)的数据交换。

SWP指令主要是完成ARM体系架构处理器的同步操作,在Linux操作系统中实现信号量的操作。但是此指令在ARMv6架构后就没有采用了,而是通过扩展的LDREX和STREX实现。本片文章主要介绍SWP的功能,对于LDREX和STREX以后再介绍。

SWP的指令格式如下:

SWP {}{B}  Rd,  Rm,  [Rn]



其中Rd是目的寄存器,从存储器中读到的值存放于此寄存器中

Rm寄存器是操作数,会将此寄存器中的值存放于存储单元中

[Rn]是寄存器间接寻址,Rn保存的是某个存储单元的地址

假设[Rn]中存放的是信号量,当某程序要修改信号量时,则会调用SWP指令完成对信号量的操作,即对这个存储单元的读和写是一个原子操作,不会被打断,命令的执行过程如下图1所示:

图1

当多个程序要访问他们共享的资源时,我们必须要做好同步机制以保证数据的安全。通常,共享的资源可以是一段共享内存或者是外部设备,访问这些资源的可以使CPU、进程或者是线程。为了完成同步机制,会采用一个原子变量来保存资源的状态。例如下图2所示,用一个二元信号量(0或者1)来实现共享资源的同步,当进程A 和 进程B都要访问信号量Semaphore。
图2

对于A进程,先访问到信号量Semaphore发现状态可用,应该马上会修改Semaphore的状态,告诉其他进程此资源正在被使用。但是可能由于时间片恰好用完,系统调度到进程B。进程B访问到信号量时发现状态也可用,于是修改Semaphore告诉其他进程此资源正在被使用,等到系统再次调度到进程A时,进程A却不知道进程B已修改了Semaphore并且使用了公共资源,于是接着上次未完成的任务,开始修改Semaphore并且开始使用公共资源。因此,遇到这种情况的话,信号量形同虚设并没有起到同步的作用。所以如果使用SWP指令,通过上面的介绍,SWP指令时完成对存储单元的一次读和写的原子操作,就可以避免这样的情况。


下面的汇编代码是通过SWP实现互斥的例子

EXPORT lock_mutex_swp

lock_mutex_swp PROC

LDR r2, =locked

SWP r1, r2, [r0]              ; Swap R2 with location [R0], [R0] value placed in R1

CMP r1, r2                      ; Check if memory value was ‘locked’

BEQ lock_mutex_swp       ; If so, retry immediately

BX lr                               ; If not, lock successful, return

ENDP

EXPORT unlock_mutex_swp

unlock_mutex_swp

LDR r1, =unlocked

STR r1, [r0]                    ; Write value ‘unlocked’ to location [R0]

BX lr

ENDP

当然,除了上面的情况,还可能由于中断的产生导致读和写的操作被打断。在一些任务比较简单的系统中,可以在关键的代码中利用禁止中断的方式来保证对数据操作的原子性,然而对于现在复杂的多任务操作系统,禁止中断的做法显然不是有效的解决方法。所以SWP通过特殊的访问方式,不需要禁止中断,但是这样也会延长中断的响应时间。随着处理器的快速发展,多核处理器已经显示出了强大的优势,同步的问题显得更加明显。如图3所示,一个系统由一个Cortex-A8和Cortex-M4组成,他们都会访问一同一段存储空间。

            
图3

SWP指令在这种模式下,就显得很尴尬了,如果依然采用原来的特殊访问模式,可能会大大降低多核处理的性能。所以从ARMv6架构以后,不再使用SWP指令实现同步的功能,而是增加了LDREX和STREX指令完成相关的操作。具体使用情况,会在LDREX和STREX的文章中详细说明。

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
原作者:宛城布衣。 本文件已移除PDF签名,如内容有误,欢迎大家指正。 目录 前言 i 目录 I ARM7TDMI(-S)指令集及汇编1 ARM 处理器寻址方式2 寄存器寻址2 立即寻址2 寄存器偏移寻址2 寄存器间接寻址3 基址寻址3 多寄存器寻址4 堆栈寻址4 块拷贝寻址5 相对寻址5 指令集介绍7 ARM 指令集7 指令格式7 第 2 个操作数7 #immed_8r 7 Rm8 Rm,shift8 条件码9 ARM 存储器访问指令 11 LDR 和 STR 11 LDM 和 STM14 SWP 17 ARM 数据处理指令19 数据传送指令20 MOV 20 MVN 20 算术逻辑运算指令20 ADD 20 SUB21 RSB 21 ADC 21 SBC 21 RSC 22 AND 22 ORR22 EOR22 IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII BIC 23 第 I 页常用 ARM 指令集及汇编 Ver:1010 比较指令23 CMP 23 CMN23 TST24 TEQ24 乘法指令25 MUL25 MLA25 UMULL25 UMLAL26 SMULL 26 SMLAL 26 ARM 跳转指令27 B27 BL27 BX 27 ARM 协处理器指令28 CDP28 LDC29 STC 29 MCR30 MRC30 ARM 杂项指令31 SWI 31 MRS 32 MSR 33 ARM指令34 ADR 35 ADRL35 LDR36 NOP37 Thumb 指令集39 Thumb 指令集ARM 指令集的区别 39 Thumb 存储器访问指令 40 LDR 和 STR 41 PUSH 和 POP 43 LDMIA 和 STMIA 43 Thumb 数据处理指令 45 数据传送指令46 MOV 46 MVN 46 NEG47 算术逻辑运算指令47 ADD 47 IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 第 II 页常用 ARM 指令集及汇编 Ver:1010 SUB48 ADC 49 SBC 49 MUL50 AND 50 ORR50 EOR51 BIC 51 ASR51 LSL52 LSR 52 ROR53 比较指令53 CMP 53 CMN54 TST54 Thumb 跳转指令 55 B 55 BL55 BX 55 Thumb 杂项指令 56 SWI 56 Thumb 伪指令 57 ADR 57 LDR57 NOP58 伪指令59 符号定义伪指令59 GBLA、GBLL、GBLS 59 LCLA、LCLL、LCLS60 SETA、SETL、SETS 61 RLIST61 CN 62 CP62 DN、SN62 FN63 数据定义伪指令63 LTORG64 MAP64 FIELD 65 SPACE66 DCB 66 DCD 和 DCDU67 DCDO 67 IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 第 III 页常用 ARM 指令集及汇编 Ver:1010 DCFD 和 DCFDU68 DCFS 和 DCFSU68 DCI69 DCQ 和 DCQU69 DCW 和 DCWU 70 报告伪指令70 ASSERT 70 INFO 71 OPT 71 TTL 和 SUBT 72 汇编控制伪指令73 IF、ELSE 和 ENDIF73 MACRO 和 MEND 74 WHIL 和 WEND 75 杂项伪指令76 ALIGN 77 AREA78 CODE16 和 CODE32 79 END 80 ENTRY80 EQU 81 EXPORT 和 GLOBAL 81 IMPORT 和 EXTERN 82 GET 和 INCLUDE 83 INCBIN83 KEEP83 NOFP 84 REQUIRE 84 PEQUIRE8 和 PRESERVE8 84 RN 84 ROUT85 ARM指令86 ADR 86 ADRL86 LDR86
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值