如何在手臂编码即时价值? [英] How to encode immediate value in arm?
问题描述
假设有一个这样的实例:
Suppose there is an inst like this:
add ip, ip, #0x5000
机器代码是
05 CA 8C E2
05 CA 8C E2
和
E2 8C CA 05 = 11100010100011001100 1010 00000101
imm = rotate_right(101B, 1010B*2) = 0x5000
但是,如果我们知道0x5000,我们怎么能得到101000000101?这种反向转换是一对一的对应吗?谢谢.
But if we know 0x5000, how can we get 101000000101? Is this reverse convert one-to-one correspondence? Thanks.
推荐答案
来自ARM ARM:
ADD
添加两个值.第一个值来自寄存器.第二个值可以是立即数,也可以是寄存器中的值,并且可以在加法之前进行移位.
ADD
adds two values. The first value comes from a register. The second value can be either an immediate value or a value from a register, and can be shifted before the addition.
您看到的立即值已发生变化.指令的第11:0位是移位器操作数-在您的情况下为 0xA05
.
The immediate value you're seeing is being shifted. Bits 11:0 of your instruction are the shifter operand - in your case: 0xA05
.
文档中稍后介绍了该寻址方式:
Later in the docs, that addressing mode is described:
< shifter_operand>
值是通过将8位立即数(向右)旋转到32位字中的任何偶数位位置而形成的.
The
<shifter_operand>
value is formed by rotating (to the right) an 8-bit immediate value to any even bit position in a 32-bit word.
因此,您特定的移位器操作数意味着将 0x05
向右旋转(2 * 10)
位.
So your specific shifter operand means 0x05
rotated right by (2 * 10)
bits.
如果要执行指令编码,则有几种选择.例如:
You have a few choices if you're doing the instruction encoding. For example:
0xA05 // rotate 0x05 right by 20
0xB14 // rotate 0x14 right by 22
0xC50 // rotate 0x50 right by 24
我手工编码了它们以进行分解:
I hand encoded them to disassemble:
$ 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
这是一个可以找到编码的简单程序:
Here's a simple program that can find the encodings:
#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;
}
并针对您的案例运行示例:
And an example run for your case:
$ ./example 0x5000
0xA05
0xB14
0xC50
这篇关于如何在手臂编码即时价值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!