Открыть список
Как стать автором
Обновить

Комментарии 14

В результате раздел данных начинается с адреса (данных) 0. Резервирование двух байтов в начале адресного пространства позволяет обеспечить то, что ни переменную, ни что-то другое в разделе данных нельзя расположить по адресу 0.


А в досе можно было положить. И на этот случай в борландовском Turbo C по этому адресу лежала строчка копирайта Borland International. А в досовском Quick C лежала строчка копирайта Microsoft. И при выполнении выхода из main CRT подсчитывало контрольную сумму этой строчки и при несовпадении жаловалось на «null pointer assignment», тем самым сообщая что где-то в программе произошло присваивание по адресу NULL (никакого защищённого режима в те времена естественно не было и никто никакие GPF и прочие иксепшены прямо в рантайме не умел).

Во какой я старый, во чего я помню!
Вау, спасибо за интересное дополнение!
Естественно «null pointer assignment» говорилось только после выхода из программы, а не при самом присваивании, GPF ведь в те времена не ловили. Так что ни конкретной переменной, ни конкретной функции, ни номера строки в которой произошла эта «бяка» узнать было невозможно, озвучивался только сам факт что «где-то вот кто-то по нулевому указателю что-то нагадил». И естественно таким образом детектировалась только запись в NULL, а не чтение оттуда.

И ещё чего вспомнил. В те времена всякие кракеры да релизеры частенько специально «портили» строчку «Turbo C++ — Copyright 1990 Borland Intl.» или «MS Run-Time Library — Copyright © 1990, Microsoft Corp», прописывая туда строку типа "-=~ Brought to ya by VeryC00l Team ~=-", а вместо строки «Null pointer assignment» вставляли какой-нибудь «Released by !M0n$teR!», в результате при штатном завершении игры CRT проверяла контрольную сумму копирайта, она само собой не совпадала и CRT выводила «Released by !M0n$teR!», чем вероятно сильно повышало ЧСВ кракера или релизера.
«Иди отсюда, мальчик, не мешай!» © :-)

Где жил PSP и что такое PSP я прекрасно знаю. Но к данной теме он никакого отношения не имеет (мы ведь не про модель памяти tiny говорим где и правда по адресу 0 был PSP, а small, medium, compact, large и huge, да? на tiny делалсь столь мало софта, что им можно пренебречь).
А по far ptr 0 таблица прерываний лежит.
Лежала. В real mode DOS. А сейчас она лежать может где угодно, инструкция sidt покажет где.
Из линкерного файла одного из современных микроконтроллеров NXP:
    __xRAM_data_start = .;
    # do NOT remove this line, as it allocates a Word at address x:0 
    # so no other valid variable gets a NULL address
    WRITEH(0x0BAD);

В начале еще была надпись Runtime error

По адресу ds:0000 лежала именно строчка с копирайтом. А всякие «runtime error», «null pointer assignment», «floating point error», "(null)" и прочие строчки ою ошибках лежали по другим адресам. А строчка с копирайтом была как раз ds:0000 и именно по её контрольной сумме CRT определяло что кто-то загадил память по нулевому указателю. Исходники CRT вам в помощь, там всё чётко и ясно откоменнтировано что, где и зачем.
Вот только при чем здесь UNIX, когда int main() это особенность Си? Перед запуском пользовательского кода стартап должен записать значения инициализации в переменные, занулить bss и т.д.
А в случае работы без ОС (в микроконтроллерах, например), нужно еще и базовую настройку провести — регистры стека, прерывания и все остальное.
И что-то мне подсказывает, что в других языках (кроме ассемблера, конечно) ситуация та же.

Когда ковыряли crt у ДВК, нашли место где вычисляется частное от деления одного полинома на другой. Так и не поняли, что это было. Может тест flow point?

Можно еще рекурсивный main() сделать для развлечения, работает.

Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

Информация

Дата основания
Местоположение
Россия
Сайт
ruvds.com
Численность
11–30 человек
Дата регистрации
Представитель
ruvds

Блог на Хабре