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. У него должна быть логика, потому что компилятор знает во время компиляции значение ПК.
+4
в режиме большого пальца, независимо от размера инструкции. Также обратите внимание, чтоbl.w
на самом деле является двумя машинными инструкциями, потому что это часть Thumb-1, в которой были только 16-битные инструкции. - person Peter Cordes   schedule 06.05.2020