0

我现在正在学习汇编语言,我对立即值的编码方式有点困惑。有人可以解释为什么以下值有效:0xff00ff00、0xffffffff、0x007f8000?另外为什么值 0xff0000ff, 0x007f9000 无效?

据我了解,12 位立即数分为 4 个高位旋转和 8 个低位常量。所以我认为我上面列出的所有值都是无效的,因为它需要超过 12 位。

关于这个主题的一些澄清会很有帮助,谢谢!

4

2 回答 2

2

(此答案适用于 ARM32 模式,而不是 Thumb2 或 AArch64。那里的情况有所不同,允许的立即数取决于指令。)

您一定在谈论 12 位编码。它实际上是 4 + 8 位编码。位置为 4,图案为 8,因此旋转计数必须是偶数。

  1. 从 0 到 255 的任何值都是有效的。0x00 ~ 0xff 模式在位置 0
  2. 256 且 N 的任意二次方均有效。因为它们都是 1bit 模式。
  3. 257 无效,因为 0x101 需要 9 位模式
  4. 258 无效,因为即使模式适合 8 位,它的位置也是奇数。(129<<1)
  5. 260 有效 (65<<2)

并且有诸如 , 等指令mvn,如果您的指令是or ,或者另一个具有在使用它之前对立即数执行某些操作的版本,cmn则很难判断一个数字是否作为立即数有效。movcmp

PS:2^4 = 16,寄存器为32bit。这就是为什么位置必须是平的。

于 2021-10-14T15:10:09.357 回答
1
.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 是吗?

于 2021-10-18T03:38:27.583 回答