Иван Савватеев @SIISII
Микроконтроллеры, цифровая электроника, ОС…
Information
- Rating
- 1,748-th
- Location
- Солнечногорск, Москва и Московская обл., Россия
- Date of birth
- Registered
- Activity
Specialization
Embedded Software Engineer
Lead
Микроконтроллеры, цифровая электроника, ОС…
Не только советских: "у них" тоже регулярно попадается direct addressing и indirect addressing.
Сначала б почитали, о чём выше писалось. Адресация всего адресного пространства в 64-разрядном режиме -- не прямая, где адрес является частью кода команды, а косвенная -- через содержимое регистра (или индексная -- адрес формируется как сумма базового адреса в регистре и индекса). Вот в 32- и 16-разрядных режимах прямая адресация тоже имеется.
Вообще-то, это переключение контекста...
Для реального режима писали, а не для защищённого. Это возможно и на современном ПК. Я вот на днях ухитрился поставить MS DOS на один из моих ПК (Ryzen-что-то-там, наизусть не помню), причём на SSD. Правда, в какой-нибудь там Диггер поиграть затруднительно: кнопка Turbo не предусмотрена :)
В 16-разрядном защищённом режиме, появившемся в 80286, были таблицы описателей (дескрипторов), а сегментные регистры содержали именно селекторы, выбиравшие описатели из этих страниц. "Число, которое домножалось на 16" -- это только для реального режима, который был единственным для 8086 и поддерживается до сих пор.
80386 в своём защищённом режиме сохранил все возможности 80286, в том числе и использование селекторов сегментов для выборки описателей этих сегментов из соответствующих таблиц (только сами описатели были расширены -- помимо унаследованных для 16-разрядного кода, добавились новые для 32-разрядного кода), но добавил ко всему этому возможность использования страниц, которую можно было включать, а можно и не включать.
Ну, собсно, подобная конфигурация -- почти типичный IBM PC. У него же флопов могло и не быть, а вот поддержка магнитофона была всегда (позже её выпилили). Правда, вместо CGA мог быть MDA, а оперативы могло быть ващще 16 Кбайт.
Это именно EXE-файл, достаточно глянуть его в любом просмотрщике. DOS определяет, что за файл ей подсунули, не по расширению, а по его началу: видит сигнатуру EXEшника -- обрабатывает соответствующим образом.
Вроде б, с этим даже уязвимости были что в ДОСе, что в Винде: можно подсунуть файл с расширением, как у, скажем, картинки, а в действительности EXEшник, и система его запускала. Но не помню, действительно ли такое было, а искать лениво :)
Загрузить в регистр можно, а прямо указать в качестве адреса данных, вроде бы, нельзя. Ну а если адрес в регистре, то получаем уже адресацию относительно регистра, о чём я и говорил.
От задачи зависит. Если там, главным образом, вычисления или нечто подобное, то язык высокого уровня будет сильно читаемее, конечно. А вот если сплошные "проверить бит -- установить бит", то на асме, как по мне, даже лучше оказаться в плане читаемости может. Поэтому, скажем, драйвер некоей железяки на асме если и сложней в плане читаемости будет, чем на сях, то несильно, а вот какой-нить мозговыносительный научный расчёт... (вспомнил советскую программу расчёта зарплаты для детсадов, школ и т.п. учреждений, написанную горячими литовскими парнями на ассемблере М-5000 и затем крутившуюся на спецпроцессоре СМ-1600 -- и как весело было, когда Союз распался и потребовалось увеличивать разрядности полей данных :) ).
Ну, были ж проекты и на несколько миллионов строк на ассемблере -- правда, не в одно рыло, но тем не менее. А в одиночку вполне реально написать проект на 50-100 тысяч строк. (Ядро RSX-11 имеет меньше, если что, -- а это, как ни крути, полноценная многозадачная ОС, пускай и с очень скромным API, если сравнивать с современными монстрами).
А насчёт переделок -- с кодом на Си ничуть не лучше, если его не комментировать. Ведь без комментариев непонятно, почему автор сделал так, а не иначе -- а, вполне может быть, для иногда очень странного кода есть разумная причина (скажем, нужно обходить ошибку в железе, совершая странные телодвижения с регистрами устройства).
Это да, но очень многие ошибки на Си возникают из-за неопределённого поведения, разрешённого стандартом, но нелепого с точки зрения здравого смысла. И если на старые версии стандартов повлиять, понятное дело, нельзя, то в новых можно было бы радикально сократить количество UB -- но это не делается.
Странных людей на хабре хватает :)
A000 -- это что, в данном случае? Сегмент, т.е. физический адрес A0000? А запрещает использовать, начиная с 9FFF0? Если да, то довольно странным выглядит. Но, может, не первый запрещённый сегмент, а последний разрешённый?
Само по себе "откусывание" какого-то объёма ОЗУ непосредственно перед A0000 -- явление нормальное, довольно многие BIOS хранят там некие расширенные данные. Но такое откусывание происходит килобайтами, поскольку именно их INT 12h возвращает, а вот чтоб параграф...
Вроде б, была в INT 21h функция "заполучить память после конца программы", но голову на отсечение не дам, смотреть надо.
Имел-имел. Не помню, была ли модель tiny, т.е. возможность создания COM-файлов, но остальные были.
Скорей всего, произошло смешивание в одну кучу имеющегося набора команд AMD64/Intel64 и разрядности адресов, используемых процессорами этой архитектуры.
"48-битный или сколько там" -- это, скорей всего, про физический адрес (сколько линий адреса выведена из процессора наружу -- к контроллеру памяти и на шину) и про то, сколько разрядов виртуального адреса можно фактически использовать при адресных вычислениях в процессоре. В этой архитектуре, спасибо AMD, а затем и Интелу, принято откровенно дурацкое решение ограничить виртуальные адреса в фактической разрядности, см. "канонические адреса" в описании архитектуры (в ряде других 64-разрядных архитектур, в частности, в z/Architecture, виртуальный адрес является всегда 64-разрядным независимо от того, сколько разрядов физического адреса выходит потом наружу -- т.е. нет ограничений на используемые виртуальные адреса).
В плане же системы команд, насколько помню, нет возможности в одной команде прямо указать 64-разрядный адрес. Т.е. в 16- или 32-разрядном коде можно написать что-то вроде MOV EAX, addr32, где addr32 -- полный 32-разрядный адрес памяти; а в 64-разрядном коде такой возможности нет, и сформировать 64-разрядный адрес можно только косвенно -- используя сумму 64-разрядного содержимого какого-либо регистра и заданное в команде 32-разрядное смещение.
Это, конечно, создаёт некоторые затруднения, но, на самом деле, крайне небольшие, и их уже много десятилетий компиляторы успешно решают на других платформах. Скажем, в Системе 360 (из которой выросла упоминаемая мною выше современная z/Architecture) в команде можно задать только 12-разрядное смещение (называемое displacement) относительно содержимого какого-либо из общих регистров, а прямой адресации памяти там нет в принципе (не считая возможности прямо адресовать младшие 4 Кбайта памяти -- для чего как раз хватает разрядности смещения). В ARM то же самое: адресация памяти всегда ведётся относительно регистров, а не прямо.
OS/360 -- конвейеров нет, семафоров нет, даже защита памяти не обязательна -- а многозадачность есть. Вытесняющая.
RSX-11 -- конвейеров нет, семафоров нет, даже защита памяти не обязательна -- а многозадачность есть. Вытесняющая.
Ну а какие конвейеры с семафорами Вы нашли в 80286, для меня остаётся загадкой. Хоть бы пояснили, что ли.
И на AT тоже не пойдёт, для него минимум -- 80386 :)
Нет, все ДОСы сами по себе работают в реальном режиме, и поэтому программа имеет полный доступ к любому железу.
Насчёт конвейеров и семафоров не понял, но для вытесняющей многозадачности не нужно ничего, кроме таймера -- чтобы по прерыванию снять задачу, слишком долго занимающую процессор. Всё это имелось уже в самом первом ПК на 8088. Защита памяти для многозадачности не требуется (она позволяет защищать задачи и систему, но не нужна для переключения задач, т. е. для собственно многозадачности).
Xenix не пошёл не из-за механизма виртуализации памяти 80286 как такового, а из-за этого, что этот механизм не позволял сохранить совместимость с ДОС, а значит, исключал использование в Xenix уже весьма и весьма многочисленных программ, написанных под ДОС. В 80836 ввели режим виртуального 8086 (по сути, не настоящий режим, а подрежим защищённого 32-разрядного режима), что и позволило создать систему, способную выполнять как собственные программы, так и программы ДОС.
Кстати, в современных 64-разрядных системах использовать программы для ДОС нельзя, поскольку режим V86 из 64-разрядного режима был выпилен, он может использоваться лишь в 32-разрядном защищённом режиме.
Вообще, это от системы зависит.
В RSX-11M (бабка Винды) и в VAX/VMS (мамаша Винды) привилегированная задача могла получить доступ к железу напрямую, попросив об этом ОС (что позволяло писать драйверы, являющиеся не частью ядра системы, а задачами режима пользователя; в частности, в RSX-11M именно так были сделаны драйверы файловых систем). Вот непривилегированная задача получить доступ к железу не могла.
А в OS/360 была вообще макрокоманда супервизора (т. е. функция API ядра системы) с весьма говорящим названием MODESET. Как говорится, угадайте с трёх попыток, что она делает :) (и да, она, в принципе, могла использоваться кем угодно, если это не было специальным образом заблокировано и оставлено лишь для избранных).
Вообще, offset всегда переводится как смещение, а не как сдвиг.