> MBR - классический пример. Очень нишевой и не очень актуальный, Настолько, что в более современных платформах даже начальные загрузчики такого плана пишут на сях. На асме максимум небольшой кусочек стартапа. В опенсорсной реализации загрузчика RasPi нехорошие люди аж плюсоту воткнули. Прикинь?
> Но да, asm() - хорошая замена асму, ага
Типа того. На нем пишут "интринсики", небольшие куски типа стартапа, и проч а основная тушка на си. Чтобы не иметь удовольствие кодить на асме.
А bios редгад и винтел уже обозвали легаси. Федора даже его повыпилить хочет. Так что пример хороший но 20 лет назад смотрелся убедительнее. X86 real mode вообще откровенное легаси.
> Т.е. нет (fPIC точно так же вызывает "соседнюю" функцию через got), но
> опять "не считается"?
Там есть опции типа танцев относительно регистра, как я понял он берется за базу и относительная адресация пляшет вокруг. Но если надо на x86, не дай боже 32-битном, на нем PIC в принципе нормально не получится. И проблема в том что у проца архитектура уродская: нормальной относительной адресации нет. А на арм можно и потрепыхаться - он умеет относительно регистра. В силу симметрии даже относительно program counter. Если обратить внимание армовские компилеры даже non-pic код любят так оформлять, перемешивая с константами. Чтобы эффективнее адресовать. И там есть отдельный руль что все константы в секцию RODATA не мешая с кодом, как на х86, ценой сильной потери эффективности. Права R-X на секцию не есть какая-то проблема и обычно никто не жалуется.
> Какая-то липовая замена (не говоря уж о том, что может потребоваться напрямую
> к регистрам или считать память по смещению) ...
В общем случае в именно регистры, именно проца, именно неадресуемые как память соваться - ну такое себе очень отдельное и специфичное развлечение. Нужное лишь иногда.
На каком-нибудь Cortex M можно вообще без этого. Правда IRQ запретить/разрешить без асмового интринсика к глобальному флагу - криво, но вообще он взлетает, одним си без ничерта. Да, на си можно написать и startup самому себе. Внутрях него допущения не совпадают со стандартом.
А так на тебе фокус:
volatile uint32_t * hw_reg = (volatile uint32_t *) 0x100500;
* hw_reg = 10;
И это, указатель менять можно, хоть по всей памяти шарься. Другое дело если там памяти нет или прав на запись нет - ну извини. Но тебе за это в тыкву и на асме так же прилетит. Именно так с железом и работают. Вот прям из сей. Оформляют регистры читабельными именами и ходят по их адресу. Вон то запишет 32 бита с числом 10 в адрес 0x100500. На чтение тоже работает, я так и читал койчей бутром - по адресу. В сях даже функции можно из таблицы кода на лету импортировать. Читаем таблицу, берем адрес, назначаем его указателю на функцию и - все, это можно вызывать как функцию с заявленным прототипом. Актуально если хочется себе нечто типа BIOS организовать, с импортом из него кода в основную прошивку например. А чтоб 2 раза тот же код не переть в бутлоадер и фирмвар например.