Ответ на загадку про ARM
2023-09-18 22:30Чтобы определить, как же работает машинная команда "mov r1, pc" на процессоре с архитектурой ARMv6-M, я сваял простую програмку.
Вот как выглядит дизассемблированный машинный код:
Верно я подозревал, что не всё так просто с этой командой MOV. Не зря эту возможность убрали в архитектуре aarch64.
Результат:unsigned pc, base;
asm volatile(
" adr %1, base \n"
"base: mov %0, pc \n"
: "=r" (pc), "=r" (base)
);
printf("base = %08x\n", base);
printf("pc = %08x\n", pc);
То есть имеем смещение +4 байта. Что несколько неожиданно, так как размер самой команды MOV всего два байта. То есть PC пролетает вперёд на лишнюю команду.base = 10000330
pc = 10000334
Вот как выглядит дизассемблированный машинный код:
Видим, что ассемблерная команда ADR превратилась в ADD того же регистра PC с константой. Но в случае команды ADD значение PC не пролетает вперёд, а честно указывает на следующую команду.1000032e: a100 add r1, pc, #0
10000330 <base>:
10000330: 467d mov r5, pc
Верно я подозревал, что не всё так просто с этой командой MOV. Не зря эту возможность убрали в архитектуре aarch64.

no subject
Date: 2023-09-19 06:33 (UTC)А всегда ли не пролетает? Что, если сдвинуть `ADD` на 2 байта?
Тут пишут https://devblogs.microsoft.com/oldnewthing/20210602-00/?p=105271 :
the resulting value is then rounded down to the nearest multiple of 4, in order to make it possible to load pc-relative words from memory.
no subject
Date: 2023-09-19 07:30 (UTC)no subject
Date: 2023-09-19 07:48 (UTC)видимо PC округляется только когда участвует в косвенной адресации
no subject
Date: 2023-09-19 08:02 (UTC)no subject
Date: 2023-09-20 16:58 (UTC)no subject
Date: 2023-09-20 17:09 (UTC)Ну или другой бранч аналогично.