Код разобранной руки, кажется, отключился из-за одной ошибки

Я компилирую тестовый код для встроенного чипа ARM, используя тестовый файл C.

test.c составляет:

      int main(){
  *(int*)0xFFFFF400 = 7;
}

Я компилирую файл с помощью следующей команды

      arm-none-eabi-gcc -march=armv4 -mtune=arm7tdmi -specs=nosys.specs -Wall -o test test.c

Которая компилируется без нареканий, потом разбираю сборку с

      arm-none-eabi-objdump -d ./test

Что дает длинный вывод со следующим main() раздел:

      00008018 <main>:
    8018:       e3e03000        mvn     r3, #0
    801c:       e3a02007        mov     r2, #7
    8020:       e3a00000        mov     r0, #0
    8024:       e5032bff        str     r2, [r3, #-3071]        ; 0xfffff401
    8028:       e1a0f00e        mov     pc, lr

Почему написано 0xfffff401 вместо 0xfffff400? Почему вычитается 3071 вместо 3072?

1 ответ

Решение

В mvnИнструкция записывает в регистр побитовое инверсное значение своего операнда. Поразрядная инверсия 0 - это все 1 бит, который в дополнении до двух представляет -1. Тогда адрес [r3, #-3071] равно −1 + −3071 = −3072.

Я не знаю, почему компилятор предпочитает основывать свою адресацию на -1, а не на 0.

Другие вопросы по тегам