📄 arm 指令格式和时序.htm
字号:
FD IA DB
</PRE>S 为控制两个特殊的功能,它们被汇编器指示为在指令的结束处放置“^”:
<UL>
<LI>如果设置了 S 位,并且指令是 LDM 而 R15 在寄存器列表中,则:
<UL>
<LI>在 26-bit 特权模式下,装载 R15 的所有 32 位。
<LI>在 26-bit 用户模式下,装载 R15 的 4 个标志位和 24 个 PC 位。忽略装载值的位 27、26、1 和 0。
<LI>在 32-bit 模式下,装载 R15 的所有 32 位,但要注意底端的两位总是零,所以忽略装载到它们的任何东西。除此之外,把当前模式的
SPSR 传送到 CPSR;因为用户模式没有 SPSR,这种类型的指令不应该用在 32-bit 用户模式下。 </LI></UL>
<LI>如果设置了 S 位,并且要么指令是 STM 要么 R15
不在寄存器列表中,则传送用户模式的寄存器而不是当前模式的寄存器。在用户模式下不应该使用这个指令。 </LI></UL>
<P>特殊情况发生在基址寄存器存在于要传送的寄存器列表中的时候。
<UL>
<LI>基址寄存器总是可以被装载而没有任何问题。但是,如果基址寄存器被装载则不能指定写回 - 你不能同时把写回值和装载值二者写到基址寄存器中!
<LI>如果不使用写回则可以存储基址寄存器而没有任何问题。
<LI>如果在存储包含基址寄存器的一个寄存器列表的时候使用了写回,则只有在基址寄存器是列表的第一个的情况下,才在写回之前写基址寄存器的值到内存。其他情况,写到内存中的值未被定义。
</LI></UL>
<P>进一步的特殊情况发生在程序计数器存在于要装载和保存的寄存器列表中。
<UL>
<LI>(在 26 位模式下) PSR 总是与 PC 一起保存((在所有模式下) PC 总是超出当前执行的指令的地址 12 字节,而不是通常的 8 字节)。
<LI>在装载时,只有在设置了 S 位的时候,才影响 PSR 的在当前模式下可改变的位。 </LI></UL>
<P>PC 不应该作为基址寄存器。
<P>块装载使用 nS + 1N + 1I + (1S + 1N 如果改变了 PC )个周期,而块存储使用 (n-1)S + 2N
个周期,这里的“n”是被传送的字的数目。
<P><A name=Software>
<H3>软件中断</H3></A><PRE>xxxx1111 yyyyyyyy yyyyyyyy yyyyyyyy
</PRE>
<P>典型的汇编语法: <PRE> SWI "OS_WriteI"
SWINE &400C0
</PRE>
<P>在遇到软件中断的时候,ARM 切换到 SVC 模式中,把 R15 的当前值保存到 R14_SVC 中,并跳转到内存中的位置 8,它假定在这里可以找到一个
SWI 处理例程来解码刚才执行的 SWI 指令的低 24 位,并以特定于操作系统的方式做与 SWI 编号有关的事情。
<P>在 ARM 上写的操作系统典型的使用 SWI 来为编程者提供各种例程。
<P>执行 SWI 指令使用 2S + 1N 个周期(加上解码 SWI 编号和执行适当例程使用的时间)。
<P><A name=CoproOp>
<H3>协处理器数据操作</H3></A><PRE>xxxx1110 oooonnnn ddddpppp qqq0mmmm
</PRE>
<P>典型的汇编语法: <PRE> CDP p, o, CRd, CRn, CRm, q
CDP p, o, CRd, CRn, CRm
</PRE>
<P>把这个指令传递给协处理器 p,告诉它在协处理器寄存器 CRn 和 CRm 上,进行操作 o,并把结果放置到 Crd 中。
<P>可以使用 qqq 提供与操作有关的补充信息。
<P>这些指令的准确意思依赖于使用的特定的协处理器;上面只是推荐的位的用法(实际上 FPA 就不遵守它)。 唯一强制的部分是 pppp 必须是协处理器编号:
协处理器设计者自由的按需要分配 oooo、nnnn、dddd、qqq 和 mmmm。
<P>如果协处理器以与推荐的不同的方式使用这些位,可能需要使用汇编器宏来对人有意义的指令语法转换成正确的 CDP 指令。对最常使用的协处理器如
FPA,许多汇编器有额外的内置助记符并自动做这个转换。(例如,汇编 MUFEZ F0,F1,#10 成等价的 CDP 1,1,CR0,CR9,CR15,3。)
<P>当前定义的协处理器编号包括: <! center BOXED ; l l. ><PRE>1 和 2 浮点单元
15 Cache 控制器
</PRE>
<P>如果做了到协处理器的一个调用而协处理器未做响应(通常因为它不存在!),则调用未定义指令向量(完全同于后面描述的未定义指令)。这用于在没有 FPA
的机器上透明的提供 FP 支持。
<P>执行这些指令使用 1S + bI 个周期,这里的 b 是协处理器在接受指令之前导致 ARM 忙等的周期数目: 这在协处理器控制之下。
<P><A name=CoproTrans>
<H3>协处理器数据传送和寄存器传送</H3></A><PRE>xxxx110P UNWLnnnn DDDDpppp oooooooo LDC/STC
xxxx1110 oooLNNNN ddddpppp qqq1MMMM MRC/MCR
</PRE>
<P>它们还是依赖于使用的特定协处理器 p。
<P>N 和 D 表示协处理器寄存器编号,n 和 d 是 ARM 处理器编号。o 是协处理器使用的操作。 M 表示协处理器自由的按需使用的位。
<P>在第一种形式中,如果 L=1 则表示 LDC,否则是 STC。这些指令分别的表现得象 LDR 或 STR,在带有立即数偏移量的各种情况下,有下列例外。
<UL>
<LI>偏移量是 4*(oooooooo),不是通常的 12-bit 常数。
<LI>如果指定了 P=0 (过后变址),则 W 必须是 1,而 W 是 1 只是指示要求写回,而不是告诉内存系统 这是一个用户模式传送。为将来的扩充保留
P=0 和 W=0 的指令。
<LI>在装载或存储一个或更多协处理器寄存器时,协处理器从 DDDD 和 N 位确定要装载或存储多少和哪个寄存器: ARM
所做的就是传送一个字到/从指示的地址,接着传送另一个到/从指示的地址 + 4,接着传送一个到/从指示的地址 + 8,以此类推,直到协处理器告诉它停止。
<LI>作为惯例,DDDD 表示要装载或存储的(第一个)协处理器寄存器,而 N 以某种方式表示长度,使用 N=1
指示一个“长”形式。协处理器设计者可以自由的忽略它...
<LI>下面是汇编语法: <PRE>LDC p,CRd,[Rn,#20] ;短形式 (N=0), 预先变址
STCL p,CRd,[Rn,#-32]! ;长形式 (N=1), 带写回的预先变址
LDCNEL p,CRd,[Rn],#-100 ;长形式 (N=1), 过后变址
</PRE></LI></UL>
<P>在第二种形式中,如果 L=1 则表示 MRC, 否则是 MCR。MRC 传送一个协处理器寄存器到一个 ARM 寄存器, MCR
做反方向传送(字母看起来象是写反了,记住在 ARM 汇编器中目的通常写在左边)。
<P>MCR 传送 ARM 寄存器 Rd 的内容到协处理器。协处理器基于 ooo、dddd、qqq 和 MMMM
字段的值自由的做它想做的任何事情,尽管有一个“标准的”解释: 把它写到协处理器寄存器 CRN,使用操作 ooo,用 CRM 和 qqq
提供可能的补充控制。汇编语法是: <PRE> MCR p,o,Rd,CRN,CRM,q
</PRE>
<P>给 MCR 指令的 Rd 不应该是 R15。
<P>MRC 从协处理器传送一个单一的字并把它放置到 ARM 寄存器 Rd 中。协处理器使用与 MCR
相同的字段自由的以任何方式生成这个字,有一个标准的解释:它来自 CRN,使用操作 ooo,用 CRM 和 qqq 提供可能的补充控制。汇编语法是: <PRE> MRC p,o,Rd,CRN,CRM,q
</PRE>
<P>如果给 MRC 指令的 Rd 是 R15,使用传送的字的顶端 4 位来设置标志;丢弃余下的 28 位。(例如,这种机制用于浮点比较指令。)
<P>执行 LDC 和 STC 使用 (n-1)S + 2N + bI 个周期, MRC 使用 1S+bI+1C 个周期,而 MCR 使用 1S +
(b+1)I + 1C 个周期,这里的 b 是协处理器在接受指令之前导致 ARM 忙等的周期数目: 这在协处理器控制之下,而 n
是传送的字的数目(注意这在协处理器而不是 ARM 的控制下)
<P><A name=Swap>
<H3>单一数据交换(ARM 3 和以后,包括 ARM 2aS)</A> </H3><PRE>xxxx0001 0B00nnnn dddd0000 1001mmmm
</PRE>
<P>典型的汇编语法: <PRE> SWP Rd, Rm, [Rn]
</PRE>
<P>这些指令装载一个内存的一个字(用寄存器 Rn 给出地址)到一个寄存器 Rd 并存储寄存器 Rm 到相同的地址。Rm 和 Rd
可以是同一个寄存器,在这种情况下交换寄存器和内存位置的内容。装载和存储操作通过设置 LOCK
引角(pin)为高电平来在操作期间锁定在一起,这指示内存管理器它们应当被没有中断的完成。
<P>如果设置了 B 位,则传送一字节的内存,否则传送一个字。
<P>Rd、Rn、和 Rm 都不能是 R15。
<P>执行这个指令使用 1S + 2N + 1I 个周期。
<P><A name=Status>
<H3>状态寄存器传送(ARM 6 和以后)</A> </H3><PRE>xxxx0001 0s10aaaa 11110000 0000mmmm MSR 寄存器形式
xxxx0011 0s10aaaa 1111rrrr bbbbbbbb MSR 立即数形式
xxxx0001 0s001111 dddd0000 00000000 MRS
</PRE>
<P>典型的汇编语法: <PRE> MSR SPSR_all, Rm ;aaaa = 1001
MSR CPSR_flg, #&F0000000 ;aaaa = 1000
MSRNE CPSR_ctl, Rm ;aaaa = 0001
MRS Rd, CPSR
</PRE>
<P>设置 s 位时意味着访问当前特权模式的 SPSR,而不是 CPSR。只能在特权模式下执行这个命令的时候设置此位。
<P>使用 MSR 来传送一个寄存器或常数到一个状态寄存器。
<P>aaaa 位接受下列值: <! center BOXED ; l l. ><PRE>值 意思
0001 设置有关的 PSR 的控制位。
1000 设置有关的 PSR 的标志位。
1001 设置有关的 PSR 的控制位和标志位(就是说所有现存的位)。
</PRE>其他的值为将来的扩充而保留。
<P>在寄存器形式中,源寄存器是 Rm。在立即数形式中,来源是 #b, ROR #2r。
<P>R15 不应该被指定为 MRS 指令的源寄存器。
<P>使用 MRS 来传送处理器的状态到一个寄存器。
<P>dddd 位存储目的寄存器的编号;Rd 一定不能是 R15。
<P>N.B. 指令编码对应于对应与操作码(opcode)是 10xx 并清除了 S 位的数据处理指令(就是测试指令)。
<P>执行这些指令总是使用 1S 个周期。
<P><A name=Undefined>
<H3>未定义指令</H3></A><PRE>xxxx0001 yyyyyyyy yyyyyyyy 1yy1yyyy 专属 ARM 2
xxxx011y yyyyyyyy yyyyyyyy yyy1yyyy
</PRE>
<P>这些指令目前未定义。在遇到未定义指令时,ARM 切换到 SVC 模式(在 ARM 3 和以后)或 Undef 模式(在 ARM 6 和以后),把 R15
的旧有值放置到 R14_SVC (或 R14_UND)中并跳转到一个位置,在那里它希望找到解码这个未定义指令的代码并相应的执行它。
<P>注意:
<UL>
<LI>这些指令被文档为“未定义的”,原因是这种方式下它们进入未定义指令处理器陷阱。许多其他指令是以更宽松的方式未被定义的,而不说出它们做什么。
例如,下面形式的位模式(pattern): <PRE> xxxx0000 01xxxxxx xxxxxxxx 1001xxxx
</PRE>与数据处理的指令、乘法、长乘法和 SWP 指令有关,但却不是其中一个的原因是:
<UL>
<LI>数据处理指令的位 25 = 0 和位 4 = 1 时有寄存器控制的移位,所以必须位 7 = 0。
<LI>乘法指令的位 23:22 = 00。
<LI>长乘法指令的位 23:22 = 1U。
<LI>SWP指令的位 24 = 1。
</LI></UL>这些指令只是简单的未定义做什么,但是上面列出的那些指令实际上<B>定义</B>为进入未定义指令陷阱,至少直到将来为它们找到某种用途。
<LI>注意“专属 ARM2”的未定义指令包括了在 ARM3/ARM2as 和以后成为 SWP 的那些指令。 </LI></UL>
<P>
<HR>
<A name=Credits>
<H2>Credits</H2></A>
<P>This document was originally written by Robin Watts, with considerable
consultation with Steven Singer. It was then later updated by Mark Smith to
include more information on ARMs later than 2.
<P>David Seal provided a huge list of corrections and amendments, and
unwittingly provided the basis for the timing information in a posting to
usenet.
<P>Various corrections were also submitted/posted by Olly Betts, Clive Jones,
Alain Noullez, John Veness, Sverker Wiberg and Mark Wooding.
<P>Thanks to everyone that helped (and if I have missed you here, please let me
know.)
<P><B>Just because I have included peoples addresses here, please do not take
this as an invitation to mail them any questions you may have!</B> <PRE>Olly Betts olly@mantis.co.uk
Paul Hankin pdh13@cus.cam.ac.uk
Robert Harley robert@edu.caltech.cs
Clive Jones Clive.Jones@armltd.co.uk
Alain Noullez anoullez@zig.inria.fr
David Seal <address withheld by request>
Steven Singer s.singer@ph.surrey.ac.uk
Mark Smith ee91mds2@brunel.ac.uk
John Veness john@uk.ac.ox.drl
Robin Watts Robin.Watts@comlab.ox.ac.uk
Sverker Wiberg sverkerw@Student.csd.UU.SE
Mark Wooding csuov@csv.warwick.ac.uk
</PRE>
<P>For those not on the internet, messages can be sent by snail mail to: <PRE>Robin Watts
St Catherines College,
Oxford,
OX1 3UJ
</PRE></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -