Код разобранной руки, кажется, отключился из-за одной ошибки
Я компилирую тестовый код для встроенного чипа 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.