首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

CM3 中一些前卫的指令(3)

CM3 中一些前卫的指令(3)

4.4.6   RBIT
RBIT 比前面的 REV 之流更精细,它是按位反转的,相当于把 32 位整数的二进制表示法水平旋 转 180 度。其格式为:
RBIT.W    Rd,    Rn
这个指令在处理串行比特流时大有用场,而且几乎到了没它不行的地步(不信可以去写段程序 完成它的功能,看看颠来倒去的能不能把你“转晕”)。
例如,记 R1=0xB4E10C23(二进制数值为1011,0100,1110,0001,0000,1100,0010,0011),
RBIT.W R0,    R1
执行后,则R0=0xC430872D(二进制数值为 1100,0100,0011,0000,1000,0111,0010,1101) 这条指令单独使用时看不出什么作用,但是与其它指令组合使用时往往有特效,高级技巧常用
到它。
4.4.7   SXTB, SXTH, UXTB, UXTH
这 4 个指令是为了体贴 C 语言的强制数据类型转换而设的,把数据宽度转换成处理器喜欢的 32 位长度(处理器字长是多少,就喜欢多长的整数,其操作效率和存储效率都最高)。它们的语法如 下:
SXTB      Rd,  Rn SXTH      Rd,  Rn SXTB      Rd,  Rn UXTH      Rd,  Rn
对于 SXTB/SXTH,数据带符号位扩展成 32  位整数。对于 UXTB/UXTH,高位清零。例如,记
R0=0x55aa8765,则
SXTB
R1,
R0
;
R1=0x00000065
SXTH UXTB UXTH
R1, R1, R1,
R0
R0
R0
;
;
;
R1=0xffff8765
R1=0x00000065
R1=0x00008765
4.4.8   BFC/BFI,UBFX/SBFX
这些是 CM3 提供的位段操作指令,这里所讲的位段与 C 语言中的位段是一致的,它们与系统程 序和单片机程序非常对口。
BFC(位段清零)指令把 32 位整数中任意一段连续的2 进制位 s 清 0,语法格式为:
BFC.W       Rd,     #lsb,       #width
其中,lsb 为位段的末尾,width 则指定在 lsb 和它的左边(更高有效位),共有多少个位参与操
作。
例如,
LDR    R0,=0x1234FFFF BFC    R0,#4, #10
执行完后,R0= 0x1234C00F
译注:位段不支持首尾拼接。例如, BFC    R0, #27, #9 将产生不可预料的结果
BFI(位段插入指令),把某个寄存器按 LSB  对齐的数值,拷贝到另一个寄存器的某个位段中, 其格式为
BFI.W
Rd,
Rn,     #lsb,
#width
例如,
LDR
R0,
=0x12345678

LDR BFI.W
R1, R1,
=0xAABBCCDD R0, #8,#16

则执行后,R1= 0xAA5678DD  (总是从Rn 的最低位提取,#lsb 只对Rd 起作用——译注)
UBFX/SBFX 都是位段提取指令,语法格式为:
UBFX.W      Rd,     Rn,     #lsb,       #width
SBFX.W      Rd,     Rn,     #lsb,       #width
UBFX 从 Rn 中取出任一个位段,执行零扩展后放到 Rd 中(请比较与 BFI 的不同)。例如:
LDR       R0,    =0x5678ABCD UBFX.W    R1,    R0, #12,#16
则 R0=0x0000678A
类似地,SBFX 也抽取任意的位段,但是以带符号的方式进行扩展。例如:
LDR       R0,    =0x5678ABCD SBFX.W    R1,    R0, #8,#4
则 R0=0xFFFFFFFB
上述例子为了描述方便使用了4 比特对齐的#lsb 和#width,但事实上并无此限制——译注
4.4.9   LDRD/STRD
CM3 在一定程度上支持 64 位整数。其中 LDRD/STRD 就是为 64 位整数的数据传送而设的,语法 格式为:
LDRD.W      RL, RH, [Rn, #+/-offset] {!};可选预索引的64位整数加载 LDRD.W      RL, RH, [Rn],#+/-offset    ;后索引的64位整数加载 STRD.W      RL, RH, [Rn, #+/-offset] {!};可选预索引的64位整数存储 STRD.W      RL, RH, [Rn],#+/-offset    ;后索引的64位整数存储
例如,记 (0x1000)= 0x1234_5678_ABCD_EF00:则
LDR       R2, =0x1000       ; LDRD.W    R0, R1,[R2]
执行后, R0= 0xABCD_EF00,    R1=0x1234_5678
同理,我们也可以使用 STRD 来存储 64 位整数。在上面的例子执行完毕后,若执行如下代码:
STRD.W    R1, R0,[R2]
执行后, (0x1000)=0xABCD_EF00_1234_5678,从而实现了双字的字序反转操作。
4.4.10  TBB,TBH
高级语言都提供了“分类讨论”式控制结构,如 C 语言的 switch,Basic 语言的 Select Case。通 常,给我们的印象是比较靠后的case 执行起来效率比较低,因为要一个一个地查。有了 TBB/TBH 后, 则改善了这类结构的执行效率(可以对比 51 中的MOVC)
TBB(查表跳转字节范围的偏移量)指令和 TBH(查表跳转半字范围的偏移量)指令,分别用于 从一个字节数组表中查找转移地址,和从半字数组表中查找转移地址。TBH 的转移范围已经足以应 付任何臭长的 switch 结构。如果写出的 switch 连 TBH 都搞不定,只能说那人有严重自虐倾向。
因为 CM3 的指令至少是按半字对齐的,表中的数值都是在左移一位后才作为前向跳转的偏移量 的。又因为PC 的值为当前地址+4,故 TBB 的跳转范围可达 255*2+4=514;TBH 的跳转范围更可高达
65535*2+4=128KB+2。请注意:Both  TBB 和 TBH 都只能作前向跳转,也就是说偏移量是一个无符号 整数。
TBB 的语法格式为:
TBB.W      [Rn,          Rm]          ; PC+= Rn[Rm]*2
继承事业,薪火相传
返回列表