我现在正在学习汇编语言,我对立即值的编码方式有点困惑。有人可以解释为什么以下值有效:0xff00ff00、0xffffffff、0x007f8000?另外为什么值 0xff0000ff, 0x007f9000 无效?
据我了解,12 位立即数分为 4 个高位旋转和 8 个低位常量。所以我认为我上面列出的所有值都是无效的,因为它需要超过 12 位。
关于这个主题的一些澄清会很有帮助,谢谢!
我现在正在学习汇编语言,我对立即值的编码方式有点困惑。有人可以解释为什么以下值有效:0xff00ff00、0xffffffff、0x007f8000?另外为什么值 0xff0000ff, 0x007f9000 无效?
据我了解,12 位立即数分为 4 个高位旋转和 8 个低位常量。所以我认为我上面列出的所有值都是无效的,因为它需要超过 12 位。
关于这个主题的一些澄清会很有帮助,谢谢!
(此答案适用于 ARM32 模式,而不是 Thumb2 或 AArch64。那里的情况有所不同,允许的立即数取决于指令。)
您一定在谈论 12 位编码。它实际上是 4 + 8 位编码。位置为 4,图案为 8,因此旋转计数必须是偶数。
并且有诸如 , 等指令mvn
,如果您的指令是or ,或者另一个具有在使用它之前对立即数执行某些操作的版本,cmn
则很难判断一个数字是否作为立即数有效。mov
cmp
PS:2^4 = 16,寄存器为32bit。这就是为什么位置必须是平的。
.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 与 armv7-m(或 -a))。
正如 Jake 指出的那样,32 位 arm 指令基本上是 8 个有效位,位移一个偶数(0、2、4、6)。
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
arm 编码比 thumb 编码更容易理解,但是 arm 文档有一些例子可以让它更容易理解。
既然你提到了 0xFF00FF00 这意味着你问的是 armv7-a 还是 armv7-m 是吗?