这篇笔记记录了如下几类ARM指令:
- 状态寄存器访问指令;
- 信号量操作指令;
- 异常中断产生指令;
状态寄存器访问指令
ARM提供了两条指令用于在状态寄存器和通用寄存器直接交换数据。
- MRS:Move Register <-- State,将状态寄存器的值传送到通用寄存器中;
- MSR:Move State <-- Register,将通用寄存器的值传送的状态寄存器中;
在操作状态寄存器时,应该注意如下几点:
- 状态寄存器中未使用的位不应该做任何的修改;
- T标志位不应该手动修改,只能通过BX指令来修改;
- 状态寄存器的访问应该遵守“读取-修改-写回”的顺序;
MRS
MRS{<cond>} <Rd>, CPSR
MRS{<cond>} <Rd>, SPSR
if CondPassed(cond) then
if R == 1 then
Rd = SPSR
else
Rd = CPSR
MSR
MSR{<cond>} CPSR_<fields>, #<immediate>
MSR{<cond>} CPSR_<fields>, <Rm>
MSR{<cond>} SPSR_<fields>, #<immediate>
MSR{<cond>} SPSR_<fields>, <Rm>
if CondPassed(cond) then
if opcode[25] == 1 then
operand = 8bit_immediate >> (rotate_imm * 2)
else
operand = Rm
if R == 0 then
if field_mask[0] == 1 and InAPrivilegedMode() then
CPSR[7:0] = operand[7:0]
if field_mask[1] == 1 and InAPrivilegedMode() then
CPSR[15:8] = operand[15:8]
if field_mask[2] == 1 and InAPrivilegedMode() then
CPSR[23:16] = operand[23:16]
if field_mask[3] == 1 and InAPrivilegedMode() then
CPSR[31:24] = operand[31:24]
else
if field_mask[0] == 1 and InAPrivilegedMode() then
SPSR[7:0] = operand[7:0]
if field_mask[1] == 1 and InAPrivilegedMode() then
SPSR[15:8] = operand[15:8]
if field_mask[2] == 1 and InAPrivilegedMode() then
SPSR[23:16] = operand[23:16]
if field_mask[3] == 1 and InAPrivilegedMode() then
SPSR[31:24] = operand[31:24]
其中<fields>将状态寄存器按照8bit一组分为4个域,分配方式如下:
bits | fields标记 | 说明 |
---|---|---|
bits[31:24] | f | 条件标志位域 |
bits[23:16] | s | 状态位域 |
bits[15:8] | x | 扩展位域 |
bits[7:0] | c | 控制位域 |
信号量操作指令
软件编程中,通常使用信号量来进行进程间的互斥,实现这的基础需要一个原子操作,即在一个指令中要完成信号量的读取和修改操作,ARM提供了两条指令来完成信号操作。
- SWP:字交换指令;
- SWPB:字节交换指令;
SWP字交换指令
SWP将内存单元(地址Rn)中的值读取到Rd中,同时将寄存器Rm的内容写入到该内存单元中,如果Rd和Rm为同一个寄存器,那么相当于交换寄存器和内存单元的内容。
SWP{<cond>} <Rd>, <Rm>, [<Rn>]
if CondPassed(cond) then
if Rn[1:0] == 0b00 then
temp = Mem[Rn, 4]
elif Rn[1:0] == 0b01 then
temp = Mem[Rn, 4] >> 8
elif Rn[1:0] == 0b10 then
temp = Mem[Rn, 4] >> 16
elif Rn[1:0] == 0b11 then
temp = Mem[Rn, 4] >> 24
Mem[Rn, 4] = Rm
Rd = temp
SWPB字节交换指令
和SWP指令类似,不同点仅仅在于该指令交换的是8bit字节。
SWPB{<cond>} <Rd>, <Rm>, [<Rn>]
if CondPassed(cond) then
temp = Mem[Rn, 4]
Mem[Rn, 4] = Rm
Rd = temp
异常中断产生指令
ARM提供了两条指令用于由软件主动触发异常中断:
- SWI:软中断指令。该指令可以产生SWI异常,ARM通过该指令可以实现用户模式中对操作系统中特权模式的程序的调用,即系统调用实现的基础;
- BKPT:断点中断指令。顾名思义,该指令用于产生软件端点,供调试程序使用;
SWI软中断指令
SWI{<cond>} <immed_24>
if CondPassed(cond) then
R14_svc = address of next instruction after then SWI instruction
SPSR_svc = CPSR
CPSR[4:0] = 0b10011 // 即进入SVC模式
CPSR[5] = 0 // ARM模式
CPSR[7] = 1 // 关闭IRQ,但是不关闭FIQ
if high vectors configured then
PC = 0xFFFF_0008
else
PC = 0x0000_0008
BKPT断点中断指令
BKPT <immed_16>
if (not overriden by debug hardware)
R14_abt = address of BKPT instruction + 4
SPSR_abt = CPSR
CPSR[4:0] = 0b10111 // 即进入ABT模式
CPSR[5] = 0 // ARM模式
CPSR[7] = 1 // 关闭IRQ,但是不关闭FIQ
if high vectors configured then
PC = 0xFFFF_000C
else
PC = 0x0000_000C