2013-07-20 2 views
3

Пусть имеется инст так:Как закодировать немедленное значение под рукой?

add ip, ip, #0x5000 

машина код

05 CA 8C E2

и

E2 8C CA 05 = 11100010100011001100 1010 00000101 
imm = rotate_right(101B, 1010B*2) = 0x5000 

Но если мы знаем, 0x5000 , как мы можем получить 101000000101? Это обратное преобразование взаимно-однозначного соответствия? Благодарю.

ответ

7

От 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 
+0

Я знаю это, но мне нужен обратный e convert ... – scvyao

+0

Отредактировано для добавления некоторых примеров. –

+0

Не могли бы вы написать свою арифметику преобразования в C? convert (0x5000) = 0xA05, 0xB14, ... – scvyao

Смежные вопросы