vak: (Default)
[personal profile] vak
Чтобы определить, как же работает машинная команда "mov r1, pc" на процессоре с архитектурой ARMv6-M, я сваял простую програмку.
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);
Результат:
base = 10000330
pc = 10000334
То есть имеем смещение +4 байта. Что несколько неожиданно, так как размер самой команды MOV всего два байта. То есть PC пролетает вперёд на лишнюю команду.

Вот как выглядит дизассемблированный машинный код:
1000032e:       a100            add     r1, pc, #0
10000330 <base>:
10000330: 467d mov r5, pc
Видим, что ассемблерная команда ADR превратилась в ADD того же регистра PC с константой. Но в случае команды ADD значение PC не пролетает вперёд, а честно указывает на следующую команду.

Верно я подозревал, что не всё так просто с этой командой MOV. Не зря эту возможность убрали в архитектуре aarch64.

Date: 2023-09-19 06:33 (UTC)
ircicq: (Default)
From: [personal profile] ircicq
> случае команды ADD значение PC не пролетает вперёд

А всегда ли не пролетает? Что, если сдвинуть `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.
Edited Date: 2023-09-19 06:36 (UTC)

Date: 2023-09-19 07:48 (UTC)
ircicq: (Default)
From: [personal profile] ircicq
Спасибо
видимо PC округляется только когда участвует в косвенной адресации
Edited Date: 2023-09-19 07:50 (UTC)

Date: 2023-09-20 16:58 (UTC)
From: [personal profile] igaa
А если следующая команда - branch ?