我现在正在学习汇编语言,我对如何编码直接值有点困惑。有人能解释一下为什么以下值是有效的:0xff00ff00, 0xffffffff, 0x007f8000?另外,为什么值0xff0000ff, 0x007f9000无效?
根据我的理解,12位直接被分成4个旋转的上位和8个低位的常数。所以我认为我上面列出的所有值都是无效的,因为它需要超过12位。
澄清一下这个话题会很有帮助,谢谢!
(此答案适用于ARM32模式,而不是Thumb2或AArch64)。这里的情况有所不同,允许的立即值取决于指令。
你一定是在说12位编码。它实际上是4 + 8位编码。4表示位置,8表示模式,因此旋转计数必须是偶数。
- 0到255的任意值都是有效的。0 位置的0x00 ~ 0xff模式
- 256, N的任意2次幂都有效。因为它们都是1位模式。
- 257无效,因为0x101需要9位模式
- 258是无效的,因为它的位置是奇数,即使模式适合8位。(129 & lt; & lt; 1)
- 260有效(65<<2)
还有mvn
,cmn
等指令,如果你的指令是mov
或cmp
,或者另一个有一个版本在使用它之前对直接值做了一些事情,那么很难判断一个数字是否作为直接值有效。
PS: 2^4 = 16,寄存器为32位。这就是为什么位置必须是偶数。
.thumb
ldr r0,=0xFF00FF00
0: f04f 20ff mov.w r0, #4278255360 ; 0xff00ff00
.thumb
.cpu cortex-m0
ldr r0,=0xFF00FF00
00000000 <.text>:
0: 4800 ldr r0, [pc, #0] ; (4 <.text+0x4>)
2: 0000 .short 0x0000
4: ff00ff00 .word 0xff00ff00
看看ARM文档,它清楚地记录了即时编码是如何工作的。以及你不能做的事情。各种thumb2扩展添加了以上所示的更多特性(armv6-m vs armv7-m(或-a))。
正如Jake指出的,32位臂指令基本上是由一个偶数(0,2,4,6)移位的8位有效位。
ldr r0,=0x00000081
ldr r0,=0x00000101
ldr r0,=0x00000102
ldr r0,=0x00000204
ldr r0,=0x10000008
ldr r0,=0xEFFFFFF7
ldr r0,=0xFFFFF00F
00000000 <.text>:
0: e3a00081 mov r0, #129 ; 0x81
4: e59f0010 ldr r0, [pc, #16] ; 1c <.text+0x1c>
8: e59f0010 ldr r0, [pc, #16] ; 20 <.text+0x20>
c: e3a00f81 mov r0, #516 ; 0x204
10: e3a00281 mov r0, #268435464 ; 0x10000008
14: e3e00281 mvn r0, #268435464 ; 0x10000008
18: e3e00eff mvn r0, #4080 ; 0xff0
1c: 00000101 .word 0x00000101
20: 00000102 .word 0x00000102
手臂编码比拇指编码更容易理解,但手臂文档中的示例使其更容易理解。
既然你提到了0xFF00FF00,这意味着你在问armv7-a或armv7-m是吗?