1. 软件中断指令SWI
SWI代表“软件中断”,用于用户调用操作系统的系统例程,常称为“监控调用”。它将处理器置于监控模式,从地址0x08开始执行指令。
如果存储器的这部分区域被适当保护,就有可能在ARM上构建一个全面防止恶意用户的操作系统。但是由于ARM很少用于多用户应用环境,因此通常不要求这种级别的保护。
二进制编码
软件中断指令的二进制编码见图
说明
SWI指令用于产生软件中断,图中的24位立即数域并不影响指令的操作,它被操作系统用来判断用户程序调用程序例程的类型,相关参数通过寄存器来传递。
如果条件通过,则指令使用标准的ARM异常入口程序进入监控模式。具体地说,
将SWI后面指令的地址保存到R14_svc;
将CPSR保存到SPSR_svc;
进入监控模式,将CPSR[4:0]设置为0b10011和将CPSR[7]设置为1,以便禁止IRQ(但不是FIQ);
将PC设置为0x08,并且将执行那里的指令。
为了返回SWI后的指令,系统的程序不但必须将R14_svc拷贝到PC,而且必须由SPSR_svc恢复CPSR。这需要使用一种特殊形式的数据处理指令,这在前面介绍数据处理指令时已提及。
监控程序调用是在系统软件中实现的,因此监控程序调用从一个ARM系统到另一个系统可能会完全不同。尽管如此,大多数ARM系统在实现特定应用所需的专门调用之外,还实现了一个共同的调用子集。其中最有用的是把R0底部字节中的字符送到用户器件一端显示的程序:
SWI SWI_WritrC ;输出R0[7:0]
另一个有用的调用是把控制从用户程序返回监控程序:
SWI SWI_Exit ;返回到监控程序
汇编格式
SWI{} <24位立即数>
举例
输出字符A:
MOVR R0,#’A’ ;将’A’调入R0中…
SWI SWI_WriteC ;…打印它
输出调用语句之后的文本串的子程序:
…
BL STROUT ;输出下列信息
=“Hello World”,&0A,&0D,0
… ;返回这里
STROUTLDRB R0,[R14],#1 ;取字符
CMP R0,#0 ;检查结束标志
SWINE SWI_WriteC ;如果没有结束,则打印…
BNE STROUT ;…并循环
MOV PC,R14 ;返回
为结束执行用户程序,返回到监控程序:
SWI SWL_Exit ;返回监控
注意事项
若处理器已经处于监控模式,则只要原来的返回地址(在R14_svc)和SPSR_svc已保存,就可执行SWI,否则当执行SWI时,这些寄存器将被覆盖。
24位立即数代表的服务类型依赖于系统,但大多数系统支持一个标准的子集用于字符输入/输出及类似的基本功能。立即数可指定为常数表达式,但通常最好是在程序的开始处为所需的调用进行声明并设置它们的值,或者导入一个文件,该文件为局部操作系统声明它们的值,然后再代码中使用它们的名字。
在监控模式下执行的第一条指令位于0x08,一般是一条指向SWI处理程序的转移指令,而SWI处理程序则位于存储器内附近某处。因为存储器中位于0x0C的下一个字正是取指中止处理程序的入口,所以不能再0x08处开始写SWI处理程序。
2. 断点指令
断点指令用于软件调试,它使处理器停止执行正常指令而进入相应的调试程序。
二进制编码
断点指令的二进制编码如图
说明
当适当配置调试的硬件单元时,本指令使处理器中止预取指。
汇编格式
BKPT {immed_16}
其中,immed_16为表达式。其值为0~65 536范围内的整数(16位整数)。该立即数被调试软件用来保存额外的断点信息。
举例
BKPT ;
BKPT 0xF02C;
注意事项
只有实现V5T体系结构的微处理器支持BKPT指令。
BKPT指令时无条件的。
3. 前导0计数
与使用其他ARM指令相比,前导0计数(CLZ——仅用于V5T体系)指令CLZ能更有效地实现数字归一化的功能。
二进制编码
前导0技术指令的二进制编码见图
说明
本指令对将Rd设置为Rm中为1的最高有效位的位置数,即对Rm中的前导0的个数进行计数,结果放到Rd中。若Rm[31]=0,则Rd=32;若Rm[31]=1,则Rd=0.
汇编格式
CLZ{}Rd,Rm
举例
MOV R2,#0x17F00 ;R2=0b00000000000000010111111100000000
CLZ R3,R2 ;R3=15
注意事项
只有实现V5T体系结构的微处理器支持BKPT指令。
Rd不允许是R15(PC)