Поведение регистра ПК ARM Thumb-2

Thumb-2 имеет размеры инструкций 32 и 16 бит, которые выровнены по 2 байтам. Более того, когда инструкция выполняется, регистр ПК имеет значение двух инструкций перед ней. То есть, когда вы вводите:

    0x1 - MOV R1, [PC #xx]

Значение ПК не 0x1, а 0x1 + the size of the two instructions ahead, поэтому в случае :

  • Две 16-битные инструкции: PC = 0x1 + 4
  • Одна 16-битная и одна 32-битная инструкция: PC = 0x1 + 6
  • Две 32-битные инструкции: PC = 0x1 + 8

Такова была теория (поправьте меня, если я ошибаюсь). Но в моем ассемблерном коде есть странные вещи: здесь, когда выполняется 0x1AE, PC равен 0x1EC - 60, то есть 0x1B0, поэтому PC только что увеличился на 2.

    0x1AE 490F      LDR      r1,[pc,#60]  ; @0x1EC
    0x1B0 6008      STR      r0,[r1,#0x00]
    0x1B2 F7FFFFE9  BL.W     dly (0x08000188)

А здесь при аналогичном сценарии, когда выполняется 0x1D4, PC равен 0x1F0 - 24, то есть 0x1D8, поэтому PC увеличился на 4.

    0x1D4 4906      LDR      r1,[pc,#24]  ; @0x1F0
    0x1D6 6008      STR      r0,[r1,#0x00]
    0x1D8 F7FFFFD6  BL.W     dly (0x08000188)

Меня смущает такое поведение ПК, этот ассемблерный код Thumb-2 кажется мне нелогичным. Не могли бы вы объяснить мне, почему это происходит и что я не понимаю в поведении регистра ПК Thumb-2. У него должна быть логика, потому что компилятор знает во время компиляции значение ПК.


person Romain Delhomel    schedule 06.05.2020    source источник
comment
Посмотрите справочное руководство ARM для процессора, для которого вы программируете. Это должно снять все вопросы, которые у вас могут возникнуть.   -  person fuz    schedule 06.05.2020
comment
О значении arm pc в 16/32-битном потоке смешанных инструкций большого пальца говорится, что это плоское +4 в режиме большого пальца, независимо от размера инструкции. Также обратите внимание, что bl.w на самом деле является двумя машинными инструкциями, потому что это часть Thumb-1, в которой были только 16-битные инструкции.   -  person Peter Cordes    schedule 06.05.2020
comment
И я думаю, что подтвердил экспериментально, как и вы, процессор должен будет декодировать инструкцию, в которой он находится, и начать декодировать следующую инструкцию перед выполнением, чтобы определить смещение к lr. придерживаться дней pre-thumb2 просто добавить 4 имеет гораздо больше смысла, особенно с крошечными конвейерами в некоторых реализациях. так что +4 кажется правильным ответом.... так и есть.   -  person old_timer    schedule 06.05.2020
comment
извините, ему пришлось бы декодировать две инструкции вперед, чтобы определить размер каждой, +4, +6 или +8. перед выполнением текущей инструкции. некоторые из этих реализаций извлекают только 16 или 32 бита за раз, так что это было бы слишком дорого.   -  person old_timer    schedule 06.05.2020