假设有这样一个 inst:
add ip, ip, #0x5000
机器码是
05 CA 8C E2
和
E2 8C CA 05 = 11100010100011001100 1010 00000101
imm = rotate_right(101B, 1010B*2) = 0x5000
但是如果我们知道 0x5000,我们怎么能得到 101000000101?这是反向转换一一对应吗?谢谢。
假设有这样一个 inst:
add ip, ip, #0x5000
机器码是
05 CA 8C E2
和
E2 8C CA 05 = 11100010100011001100 1010 00000101
imm = rotate_right(101B, 1010B*2) = 0x5000
但是如果我们知道 0x5000,我们怎么能得到 101000000101?这是反向转换一一对应吗?谢谢。
从 ARM ARM:
ADD
添加两个值。第一个值来自寄存器。第二个值可以是立即数或来自寄存器的值,并且可以在加法之前进行移位。
您看到的直接价值正在发生变化。您的指令的位 11:0 是移位器操作数 - 在您的情况下:0xA05
.
稍后在文档中,描述了该寻址模式:
该
<shifter_operand>
值是通过将 8 位立即数(向右)旋转到 32 位字中的任何偶数位位置来形成的。
因此,您的特定移位器操作数意味着按位0x05
右移。(2 * 10)
如果您正在执行指令编码,您有几个选择。例如:
0xA05 // rotate 0x05 right by 20
0xB14 // rotate 0x14 right by 22
0xC50 // rotate 0x50 right by 24
我对它们进行了手工编码以进行反汇编:
$ xxd -r > example
00 05 CA 8C E2 14 CB 8C E2 50 CC 8C E2
$ arm-none-eabi-objdump -m arm -b binary -D example
example: file format binary
Disassembly of section .data:
00000000 <.data>:
0: e28cca05 add ip, ip, #20480 ; 0x5000
4: e28ccb14 add ip, ip, #20480 ; 0x5000
8: e28ccc50 add ip, ip, #20480 ; 0x5000
这是一个可以找到编码的简单程序:
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
int main(int argc, char **argv)
{
uint32_t encode = strtoul(argv[1], NULL, 0);
int rotate;
for (rotate = 0; rotate < 32; rotate += 2)
{
// print an encoding if the only significant bits
// fit into an 8-bit immediate
if (!(encode & ~0xffU))
{
printf("0x%X%02X\n", rotate/2, encode);
}
// rotate left by two
encode = (encode << 2) | (encode >> 30);
}
return 0;
}
并为您的案例运行一个示例:
$ ./example 0x5000
0xA05
0xB14
0xC50