как команда arm movw отображается на машинный код? - PullRequest
3 голосов
/ 29 января 2012

В настоящее время я пытаюсь понять, как работает инструкция movw на ARM, чтобы иметь возможность редактировать библиотеку в шестнадцатеричном формате и изменять значение, которое устанавливается с помощью указанной инструкции.

Библиотека представляет код следующим образом(вывод из objdump):

[...]
29c4:   f44f 71f0   mov.w   r1, #480    ; 0x1e0
[...]

Другими словами, я пытаюсь понять, как 0x1e0 / 480 представлен внутри "f44f 71f0".Я читал что-то в интернете, включая http://blogs.arm.com/software-enablement/251-how-to-load-constants-in-assembly-for-arm-architecture/ и думаю, что понимаю, как работает movw и его ограничения;но я до сих пор не понимаю, как значение, отображаемое в инструкции, отображается в реальном двоичном коде.Мы ценим любую документацию или информацию, которую вы можете предоставить по этому вопросу:)

Ответы [ 2 ]

2 голосов
/ 29 января 2012

Для ручного управления инструкции описаны в ARM ARM, ARM Architectural Справочное руководство (и). Перейдите к http://infocenter.arm.com, затем по левой стороне найдите архитектуру, затем найдите интересующую вас архитектуру. Это инструкция thumb2, поэтому вам нужен armv7-m.

Это выглядит как кодировка T2

11110i00010S11110... 

i и S равны нулю в вашей инструкции. imm3 - это биты с 12 по 14, а imm8 - это биты с 7 по 0.

0 111 0001 11110000

поэтому ваш imm3 равен 0b111, а imm8 равен 0b11110000

затем вы смотрите на измененные непосредственные константы в разделе инструкций большого пальца

i ... imm3 ... abcdefgh, где abcdefgh - биты imm8 вашего i: imm3: биты, 5 бит - 0b11111

так что вы посмотрите на это в таблице, и вы получите imm8 на правой стороне, смещенной влево 1

00000000 00000000 00000001 bcdefgh0
00000000 00000000 00000001 11100000

, что составляет 0x000001E0

Arm неплохо справляется с документированием своих инструкций, лучше, чем большинство.

1 голос
/ 10 апреля 2012

Вот кодировка MOV T2 (из Справочное руководство по архитектуре ARM )

11110 i 0 0010 S 1111 0 imm3 rd imm8

d = UInt(Rd); 
setflags = (S == ‘1’); 
(imm32, carry) = ThumbExpandImm_C(i:imm3:imm8, APSR.C);
if d IN {13,15} then UNPREDICTABLE;

Поскольку ваш шаблон

      i        S        imm3  rd   imm8
11110 1 0 0010 0 1111 0 111   0001 11110000

У вас естьi=1, S=0, imm3=111, imm8=11110000



Проверяя , что ThumbExpandImm_C () делает , вы поймете, как значения стали 0x1e0

// ThumbExpandImm_C()
// ==================
(bits(32), bit) ThumbExpandImm_C(bits(12) imm12, bit carry_in)
if imm12<11:10> == ‘00’ then
    case imm12<9:8> of
        when ‘00’
            imm32 = ZeroExtend(imm12<7:0>, 32);
        when ‘01’
            if imm12<7:0> == ‘00000000’ then UNPREDICTABLE;
            imm32 = ‘00000000’ : imm12<7:0> : ‘00000000’ : imm12<7:0>;
        when ‘10’
            if imm12<7:0> == ‘00000000’ then UNPREDICTABLE;
            imm32 = imm12<7:0> : ‘00000000’ : imm12<7:0> : ‘00000000’;
        when ‘11’
            if imm12<7:0> == ‘00000000’ then UNPREDICTABLE;
            imm32 = imm12<7:0> : imm12<7:0> : imm12<7:0> : imm12<7:0>;
            carry_out = carry_in;
else
    unrotated_value = ZeroExtend(‘1’:imm12<6:0>, 32);                 <--- a
    (imm32, carry_out) = ROR_C(unrotated_value, UInt(imm12<11:7>));   <--- b
return (imm32, carry_out);



Наши imm12 = i:imm3:imm8 (1:111:11110000) = 1111 1111 0000
Наши значения будут проходить через строки (a) и (b), поскольку старшие 2 бита [11,10] равны '11'

ZeroExtend ('1': imm12 <6: 0>, 32) означает, что вы должны добавить «1» к [6..0] битам.Таким образом, значение становится 1:1110000 = 11110000 (a)
ROR_C (unrotated_value, UInt (imm12 <11: 7>)) вращается вправо на [11: 7] = 11111 = 31, что является same as rotate left by 1.(б)

Таким образом, полученное значение равно 1 1110 0000 (a shifted by b) = 0x1e0

...