Результаты поиска по запросу «

линейные системы

»

Запрос:
Создатель поста:
Теги (через запятую):



английская система мер История story длиннопост Cat_Cat vk Реактор познавательный системы мер аршин 

«Короче, бесят они меня, дюймы эти их ебаные» (с) греческий мудрец.

 Итак, давайте разберемся, что за пирожки эти дюймы и пинты, ебаные они или ебучие, и как всю эту братию правильно называть в беседе с пацанами после полудюжины пинт ирландского эля.

 С момента появления возможности объясняться с ближним своим, перед человеком стояла до смешного простая, но при этом жизненно важная задача: как объяснить своему соплеменнику, насколько мамонт огромный или какую большую рыбу ты поймал. Естественно, самое простое – начать махать руками, показывая, что он вооот такой и еще пять раз вооот такой. Дело за малым – придумываем название для «вооот такой» покороче, например, «сажень» и готово – традиционная мера длины получена и будет использоваться вами и вашими соплеменниками до конца времен, потому что просто, всем понятно, практически применимо. Конечно, все руки немного разные, но кого это волнует, когда метрологию, глобальную торговлю и точное машиностроение еще не придумали? Но о недостатках поговорим в конце заметки, а сейчас еще немного примеров «естественности» традиционных единиц измерения.

 В целом, тут есть два пути. Первый – мерять своим телом. Так мы получим локти, пальцы вдоль и поперек (дюйм), ступни (футы), шаги, ноги, крылья и хвосты (зачеркнуто), а также их различные вариации, такие как сажень и косая сажень. Лично для меня тут наиболее показателен пример «четверти» (на картинке 3 – пядь), в которых мой рост с детства меряли отец и бабушка. Четверть (пядь) равна максимальной длине между большим и указательным (средним) пальцами руки. Да и сейчас это удобно, когда нет рулетки, прикинуть, влезет ли кровать между шкафом и стеной. То есть, как мы видим, применение таких единиц в повседневной жизни более удобно, чем стандартных метрических единиц.

английская система мер,История,Истории,длиннопост,Cat_Cat,vk,интернет,Реактор познавательный,системы мер,аршин
английская система мер,История,Истории,длиннопост,Cat_Cat,vk,интернет,Реактор познавательный,системы мер,аршин

                               дюйм

 Среди традиционных единиц измерения длины интересен английский ярд, принятый равным расстоянию от кончика носа до конца среднего пальца правой руки английского короля. А если король умирал, то и основная мера длины менялась. Да, это чистой воды сюр. А все почему? А потому что не стоит выносить локальную систему мер на государственный уровень, не говоря уж о мировом.

 Второй путь – мерять чем-то, что в твоем селе/городе/культуре есть у каждого. Например, в вершках, равных длине указательного пальца до второй фаланги (картинка 1), примерно соответствующих толщине вершка (сливок) на поверхности кувшина с молоком. Удобная и понятная величина, если ты и вся твоя деревня держит коров и пьет молоко (а местному авторитету сливает вершки). Или, если ты из дремучих лесов, славных своими соболями — в сорокАх, равных 40 единицам шкурок, необходимых для производства одной шубы. При этом не обязательно таким образом считать именно соболей, это просто величина, обозначающая сорок штук чего-либо, например, можно сказать «десяток сороков пряников», а можно использовать как фразеологизм, обозначающий большое число: «сияли над Москвой сорок сороков церковных главок». Отсюда происходит и необычное числительное «сорок», а не «четыредесят», как должно было бы быть по аналогии с «пятьдесят» и другими. Однако мы отвлеклись. Давайте вернемся к традиционным единицам измерения и посмотрим, что там у хохлов (зачеркнуто), как с ними обстоят дела в других культурах и эпохах.


                   

1 локоть
Локоть
Сажень
213.36 см
вля
1 пядь
Фут
30.48 см
около 71 см,английская система мер,История,Истории,длиннопост,Cat_Cat,vk,интернет,Реактор познавательный,системы мер,аршин


 В Греции и других странах античного Средиземноморья (да-да, в Риме тоже), жидкости – обычно вино и оливковое масло, как основные товары экспорта – меряли тем, во что они наливались – амфорами. Причем по особой форме амфоры, покупатель определял, откуда она, что в ней и сколько примерно стоит её содержимое. Впоследствии в результате развития торговли в Средиземном море и установления господства Рима потребовалось стандартизировать эту единицу измерения, была введена «средняя амфора», а масса, равная массе воды в ней, принята за стандартную меру массы – талант. Кто сказал «метрическая система»? Да, римляне и тут нас опередили.

 Также существовали меры объема, используемые для сыпучих веществ, среди которых самым ходовым, конечно, являлось зерно. Измерение объема в таких единицах встречается в античности: греко-римский модий, равный трети амфоры и по смыслу, по-видимому, связанный с выдачей пайка солдатам; в средневековой Руси: куль, равный объему мешка, сделанного из кожи животного и обычно используемого для хранения зерна; в средневековой и более поздних эпохах других государств, в частности, Англии.

 Предлагаю выпить по кружке английского пива и продолжить. А, кстати, традиционно пивная кружка имела объем в пинту, равную 1/8 части галлона, определяемого как объем 8 фунтов пшеницы, то есть была равна объему одного фунта пшеницы, из которой и варился дедушка пива – эль! Как и в примерах выше, все логично, хотя и весьма запутанно. И лично мне такой объем (английская пинта ~0,56 литра) нравится больше, потому что стандартной поллитрой я не напиваюсь, да и в руке такая кружка лежит как-то поприятнее.

 Упомянутый выше фунт имеет много вариантов и у каждого своя история, поэтому скажу о двух из них: торговый фунт равнялся весу 9600 зёрен, а башенный, легший в основу нынешнего фунта стерлингов, – весу 120 серебряных арабских дирхамов. Теперь становится понятна привычка любителей Имперской системы мер (определяемой фунтом, ярдом и галлоном и официально применяемой только в США, Либерии и Мьянме), мерять всё то в футбольных полях, то в бейсбольных битах. Привет, «лайнер размером с Эмпайр-стейт-билдинг и еще 25 дюймов».

 Наверняка вы заметили еще одну интересную особенность таких единиц – их кратность двойке, либо её степеням. Такие числа фигурируют потому, что делить на глазок на 10 неудобно, а вот поделить пополам, еще раз пополам, и еще раз пополам, что даст 1/8 – очень даже. Еще встречается кратность 12, основанная на счёте по фалангам пальцев (один палец состоит из трёх фаланг, пальцев четыре, большой не участвует, так как отличается), как, например, в дюжине – 12 единиц и её производных: гроссе – 144 единицы (12 дюжин) и массе – 1728 единиц (12 гроссов, 144 дюжины).

 Итак, подведем промежуточный итог о преимуществах естественной системы мер и зафиксируем, почему она так долго существовала и может ограниченно применяться до сих пор:

1. Она проста и понятна для применения в быту в рамках культуры, в которой была создана и потому могла быть применена на базаре любым крестьянином;
2. Её величины исторически определялись через простые единицы чего-либо, такие как шкуры или зерна, и, таким образом, приблизительно могли быть восстановлены без применения эталонных мер;
3. Кратность одних величин другим определена через удобные для счёта на пальцах или для деления на глазок части, кратные 8 либо 12, что было важно в эпоху отсутствия развитых вычислительных машин и удобно сейчас при их отсутствии.

 Недостатки такой системы мер очевидны читателю, как человеку, выросшему в современном мире победившей глобализации: различие амфор, мешков, шагов и других мер в зависимости от особенностей человека или культуры, либо недоброго умысла торговца и невозможность быстрого и точного перевода величин из одной системы в другую. Но эти недостатки не проявляются в местах, где отсутствует развитая торговля и обмен научными знаниями, а также при отсутствии столкновения двух различных систем, и в этом случае преимущества являются более весомыми. Так что, как мне кажется, никакие дюймы не ебучие, и даже не ебаные, а очень даже полезные в озвученных выше условиях.

 Напоследок поговорим о недостатках на примере двух баек, ярко иллюстрирующих, что бывает, если сталкиваются две различные традиционные системы мер.

 Первая байка о том, что при транзитной торговле Новгородской республики через порты, принадлежащие Ганзейскому союзу, ганзейские купцы эксплуатировали право контролировать качество товара, беря «отрез» ткани существенно большей длины, чем это было необходимо, что вызывало конфликты. Естественно, при любом торговом споре о том, кто кого обмерял, обе стороны были искренне уверены в своей правоте, аргументируя тем, что «ну вот такой у нас отрез», что нередко приводило к погромам то русского подворья на каком-нибудь Готланде, то немецкого в Новгороде. Хотя, конечно, предпринимались попытки стандартизировать это на государственном уровне введением, например, так называемых «казенных аршинов», представляющих собой деревянную линейку, на концах которой клепались металлические наконечники с государственным клеймом, но в рамках мировой торговли они были неприменимы, поскольку отличались от государства к государству и требовали существенных дипломатических усилий для приведения в соответствие друг другу.

 Вторая байка уже из наших дней. Конкретики не помню, но ты пидор (зачеркнуто), в Америке в начале 20 века произошел большой пожар, на который съехались пожарные команды со всех ближайших станций, включая и станции других штатов, и тут выяснился забавный факт: далеко не у всех из них штуцера на шлангах подходили к местным гидрантам, в результате чего часть приехавших и поднятых по тревоге людей не были заняты тушением огня. Вот такой курьез, хотя, конечно, ситуация страшная.

                    

английская система мер,История,Истории,длиннопост,Cat_Cat,vk,интернет,Реактор познавательный,системы мер,аршин

 Традиционные меры длины берут свое начало в культуре и опыте народов и более практически применимы в быту, чем метрические. Однако, как и в рассказанных историях, измерение самолетов в шагах на заводе и при составлении технического задания или торговля без единой и одинаковой для всех системы мер, приводили бы к различным неприятным вредным последствиям: падениям самолётов, обманам и ошибкам везде где только можно. Уход от традиционной системы единиц к метрической в 19-20 вв. явился следствием развития глобального обмена товарами, знаниями и технологиями.

 А про метрическую и естественную (основанную на физических константах) системы единиц как-нибудь потом ещё расскажу.

_____________________________

Автор: Иван Котов

Развернуть

Буквы на белом фоне Метрическая система английская система мера измерения единицы измерения 

"Чтобы запомнить, сколько футов в миле, вам нужно всего лишь пять помидоров (томатов)
Потому что "five to-mate-oes" звучит как пять, два, восемь, О, а в миле как раз 5280 футов"

"Чтобы запомнить, сколько метров в километре, достаточно запомнить "1000"
потому что система измерения в остальном мире не была изобрела пьяным математиком, кидающим кубик "
jfjgfe adhdheather to remember how many feet there are in a mile, u just gotta use 5 tomatoes five to-mate-oes sounds like five, two, eight, 0 and there's 5280 feet in a mile official-deutschland To remember how many meters there are in a kilometre you just remember "1000” because the system
Развернуть

Отличный комментарий!

То есть, блять, у них еще и в миле не тысяча футов? Пиздец
Mambateam Mambateam08.04.201907:06ссылка
+29.3
США Остальные страны Непонятные американские горки Всё логично Дюймов Фута Ярдов Унций в в в в футе ярде миле фунте в в в в метре километре килограмме тонне
Фиговина Фиговина08.04.201907:10ссылка
+51.6

точность мастерство система измерений рулетка 

Рулетка электрика, плиточника и мебельщика, которые делали тебе кухню. У каждого личная.,точность,мастерство,система измерений,рулетка
Развернуть

пидоры помогите ПК Windows 11 Windows Операционная система песочница 

Приветствую реакторчане!

Помогите добрым советом. Не могу настроить на Windows11 аудивыходы. 

пидоры помогите,реактор помоги,ПК,Windows 11,Windows,Операционная система,песочница

Пытаюсь сделать так что-бы в зелёный и синий был выход на динамики. Все три выхода работают, система их видит. На windows 7 настраивал (и не раз) - всё работало. Ось сменил (железо тоже самое)- не настраивает, ни в какую. К зелёному, стандартно подключаю всё работает. К синему подключаю, как настройки реалтека ни крутил не получается. Дрова переустанавливал тоже не хочет. Есть у кого мысли?

ПИДОРЫ, ПОМОГИТЕ,пидоры помогите,реактор помоги,ПК,Windows 11,Windows,Операционная система,песочница

Развернуть

программирование geek OSDev Операционная система ассемблер разработка длиннопост 

ОСдев №10: основной загрузчик, часть 3. GDT.

Подготовительный этап закончен, можно приступать к интересному. Кроме собственно загрузки файлов наша программа должна подготовить для ОС рабочую среду. Это значит: переключить процессор в 32/64-битный режим, настроить таблицу прерываний и создать базовую GDT. Сегодня разберёмся с последним пунктом.

GDT - сокращение от Global Descriptor Table, глобальной таблицы дескрипторов. Что это такое? По сути - набор записей одинакового формата, описывающих области памяти и разрешения, которые они имеют. Упрощённо это выглядит так:

//область 0

адрес области

размер области

параметры доступа

флаги

//область 1

адрес области

размер области

параметры доступа

флаги

...

В 32/64-битном режиме дескрипторные таблицы используются вместо старой схемы адресации сегмент:смещение. Зачем? Сегмент:смещение - небезопасная технология, которая позволяет переписать любой участок памяти. Надо ли говорить, что при неосторожном обращении это легко может закончиться бедой? Дескрипторная таблица даёт возможность ограничить запись или выполнение кода в отдельных областях RAM. Дескрипторные таблицы появились как часть аппаратной защиты памяти вместе с 286 процессором.

Как это работает? После выхода из 16-битного режима процессор больше не принимает адреса в формате сегмент:смещение. Если попытаетесь так сделать - получите исключение GPT (General Protection Fault). Вместо этого в сегментном регистре процессор ожидает получить смещение дескриптора внутри ДТ. При этом для операций над этим сегментом будут действовать правила, указанные в дескрипторе. Например, попытка обратиться к памяти за пределами сегмента или запись в защищённый от записи сегмент будут вызывать исключения (кстати, про обработку исключений поговорим позже, пока давайте примем, что это фатальная ошибка, которая приведёт к остановке программы).

Кроме глобальной таблицы дескрипторов существуют ещё локальные (ЛДТ), TSS и таблицы дескрипторов прерываний (IDT). Для того, чтобы наша ОС могла начать работу, обязательно наличие только двух таблиц: GDT и IDT. Давайте теперь взглянем на GDT поподробнее. Скажу сразу, зрелище будет не очень приятное. Но начнём с лёгкого. Так как GDT - часть аппаратной схемы защиты памяти, у неё есть свой регистр: GDTR. Это 48-битный регистр, 4 байта которого предназначены для смещения GDT, а 2 - для её размера. Таким образом, GDT не может быть больше 65536 байтов в размере. Размер записи в GDT - 8 байтов, значит,< таблица может иметь максимум 8192 дескриптора. Зная всё это, хорошим тоном было бы сразу зарезервировать 64К под GDT, но в моей архитектуре ОС создаёт свои таблицы, так что сейчас я обойдусь минимумом. Минимум в данном случае - 3 дескриптора. Нулевой, сегмент кода и сегмент данных. Зачем отдельно выделять нулевой дескриптор? Дело в том, что обращение к нему в GDT приводит к, вы угадали, исключению. Это тоже своего рода мера предосторожности.

А теперь время взглянуть на структуру дескриптора. И тут, увы, наследие тяжёлого прошлого во всей красе. Ради обратной совместимости в кодом для старых процессоров дескриптор GDT превратили в кашу.

Первые два байта - это первые 16 битов границы сегмента.

Следующие три байта - первые 24 бита основания сегмента.

Следующий байт - параметры доступа. Рассмотрим ниже.

Следующий байт совмещает в себе биты 16-19 границы и флаги. Об этом тоже подробнее ниже.

Ну и последний байт - биты 24-31 основания.

Неудобно? Не то слово. Когда будем писать ядро - обязательно замутим процедуру для комфортной работы с этим месивом. К счастью, сейчас у нас статичная структура всего из трёх сегментов, так что заполнить можно и вручную. Создадим и подключим модуль GDT.inc. Как это сделать, мы рассматривали в прошлый раз. И добавим в него вот такую таблицу:

;Нулевой дескриптор, сЫ 00001л бы 00001л db 001л с1Ь 00000000Ь с1Ь 00000000Ь с!Ь 001л ¿Дескриптор сегмента бы 0РРРР1л с!ы 00001л с!Ь 001л дЬ 10011010Ь с!Ь 11001111Ь с!Ь 001л ¿Дескриптор сегмента бы 0РРРР1л бы 00001л с!Ь 001л 6Ь 10010010Ь 6Ь 11001111Ь с1Ь 001л ¿Биты 0-15 предела. ¿Биты 0-15


Это и есть наша GDT, ничего ужасного. Значения в нулевом дескрипторе для нас не важны, а вот остальные давайте рассмотрим подробнее. У нас есть два дескриптора: один - для кода, другой - для данных. Оба начинаются с 0 и занимают FFFFF*4Kib = 4Gib. Фактически это значит, что, начав работать, ОС сможет использовать всю память по своему усмотрению. Давайте теперь разберём параметры доступа и флаги.

Бит 1 - флаг чтения/записи. Его значение различается для сегментов кода и данных. Для сегментов кода установленный флаг означает, что чтение разрешено. Запись в сегменты кода запрещена всегда. Для сегментов данных установленный флаг означает, что разрешена запись. Чтение из сегментов данных

Таким образом, значение параметров доступа 10010010b даёт нам вот что: это сегмент данных, запись в него разрешена, сегмент растёт вверх, уровень привилегий - ring0. А теперь флаги. Биты 0-3 здесь заняты границей сегмента, не обращаем на них внимания.

Бит 4 зарезервирован и должен быть равен 0. Бит 5 указывает на 64-битный сегмент. Так как мы пока переходим в 32-битный, должен быть равен 0. Бит 6 указывает на 32-битный сегмент. Наш выбор, устанавливаем в 1. Бит 7 - гранулярность. Если равен 0, то значение границы сегмента используется как

Окей, теперь у нас есть GDT. Но как указать системе, что её нужно использовать? Процессор ведь не дурак, сам искать не станет. Всё просто, джентльмены из IBM в кои-то веки о нас позаботились. При помощи специальной ассемблерной команды lgdt (load GDT) мы можем передать в регистр GDTR линейный адрес таблицы и её размер. Для этого добавим перед GDT такую структуру:

60ТК_р1:г: dы 00171п ;Размер таблицы - 1 (23 байта). dd 00000000И ;Абсолютный адрес таблицы.,программирование,geek,Прикольные гаджеты. Научный, инженерный и айтишный юмор,OSDev,Операционная система,ассемблер,разработка,длиннопост

Размер таблицы мы уже знаем, а вот адрес придётся посчитать, так что пока оставим 0 и напишем процедуру инициализации GDT:

init_GDT ргос init_GDT endp push eax pushfd xor eax,eax mov ax,offset GDT add eax,00000500h mov dword ptr [GDTR_ptr+2],eax cli lgdt pword ptr GDTR_ptr sti popfd pop eax ret,программирование,geek,Прикольные гаджеты. Научный, инженерный и айтишный юмор,OSDev,Операционная

На случай, если тут не всё очевидно, поясню. Мы помещаем в EAX смещение GDT относительно сегмента, а потом добавляем адрес сегмента*16. Это и есть линейный адрес, сохраняем его в структуре. После этого отключаем прерывания, передаём структуру процессору командой lgdt и включаем прерывания обратно. По идее прерывания можно не трогать, так как в 16-битном режиме GDT не используется, но я перестраховщик.

Собственно, на этом всё. Добавьте вызов init_GDT в конец загрузчика перед cli и дело в шляпе. Сегодня без картинки, но вот вам котик.

программирование,geek,Прикольные гаджеты. Научный, инженерный и айтишный юмор,OSDev,Операционная система,ассемблер,разработка,длиннопост

Чистая дискета: https://drive.google.com/file/d/1Bold4ds8oEruHQ7fJZKHglVo7A2Vc5MR/view?
Предыдущие части:
Развернуть

Windows Операционная система Мемы злость american chopper 

Устранения неполадок Windows

Windows,Операционная система,Мемы,Мемосы, мемасы, мемосики, мемесы,злость,american chopper
Развернуть

программирование geek OSDev Операционная система разработка ассемблер длиннопост песочница 

Урок ОСдева №6: минидрайвер флоппи-привода.

В предыдущем посте мы вычислили значения, нужные для работы с FAT12. Пора писать драйвер!

Начнём с постановки задачи. Что должен уметь драйвер FAT12 для первичного загрузчика?

Очень просто: загружать файлы. Больше ничего.


Для этого мы будем использовать прерывание BIOS. Кстати, про прерывания мы ещё не

говорили. Пока давайте считать, что это функции, предоставляемые для нашего удобства

BIOS. Подробно об этом говорить будем позднее, так как тема очень большая. Кроме того,

позже мы напишем полноценный драйвер, который будет работать с флоппи-приводом напрямую,

без посредства BIOS. Сделать это прямо сейчас мы не можем из-за ограничения по размеру

программы: первичный загрузчик должен занимать не больше 512 байт - полновесный драйвер

флоппи-привода в такой объём не влезет.


Прерывания вызываются командой int, после которой идёт номер. Стандартное

прерывание BIOS для работы с дисками - 13h. Соответственно, команда выглядит так: int 13h.

Как правило прерывания требуют передачи параметров через определённые регистры. Так,

int 13h нужен номер функции в AH. Прерывание 13h - это целый набор функций для работы

с различными видами съёмных и постоянных носителей. Нас интересует функция 2, чтение

секторов с диска. Она в свою очередь требует указать количество считываемых секторов в AL,

номер цилиндра в CH, номер начального сектора в CL, головку в DH, привод в DL и адрес

в памяти, куда будут считаны данные, в ES:BX.


Итак, ещё раз: в нашем случае int 13h вызывается со следующими параметрами:

AH = 2 (номер функции)

AL = число секторов

CH = номер цилиндра

CL = номер начального сектора

DH = номер головки

DL = 0 (номер привода)

ES:BX = сегмент:смещение области для загрузки


Прерывание int 13h у нас будет вызываться в процедуре read_sectors. Этой последней нужно

будет передать три параметра: LBA в AX, число секторов в CX и адрес для загрузки в ES:BX.

Что такое LBA мы уже знаем: это более современная линейная схема адресации секторов. К сожалению,

прерывание 13h работает с устаревшим форматом CHS, так что придётся делать конверсию

внутри процедуры.


Кстати, стоит сразу остановиться на том, как оформляются и что представляют собой процедуры

в TASM. В коде процедура выглядит так:


(имя процедуры) proc

     (тело процедуры)

(имя процедуры) endp


Обе эти инструкции нужны только компилятору и в исполняемый файл не попадают. В случае

"плоского" бинарного файла процедура окажется именно там, где она расположена в тексте

программы - никакой отдельной области памяти для неё создаваться не будет. Процедура

вызывается инструкцией call (имя процедуры). Предварительно, конечно, надо поместить

нужные параметры в нужные регистры.


Теперь немного о внутреннем устройстве FAT12. Для того, чтобы загрузить файл в память,

нам нужно проделать следующие вещи:


1. Загрузить в память Корневую Директорию диска.

2. Найти в КД запись, соответствующую файлу.

3. Считать из записи номер первого кластера файла в FAT.

4. Загрузить в память FAT.

5. Загрузить в память цепочку кластеров, которую занимает файл.


В этот раз мы ограничимся только первым пунктом, всё остальное будет в финальной статье

про первичный загрузчик. Давайте вспомним, как выглядела программа в конце прошлого поста:


.386p

CSEG segment use16

ASSUME cs:CSEG, ds:CSEG, es:CSEG, fs:CSEG, gs:CSEG, ss:CSEG

begin:                              jmp short execute;Точка входа. Перейти к исполняемой части.

                                       nop;Пустой оператор. Заполняет 3-й байт перед BPB.




;БЛОК ПАРАМЕТРОВ BIOS==========================================================;


     ;=======================================;

     ;Блок параметров BIOS, 33 байта.                                         ;

     ;Здесь хранятся характеристики                                            ;

     ;носителя. Должен быть в 3 байтах                                       ;

     ;от начала загрузочного сектора.                                          ;

     ;=======================================;

     BPB_OEMnamedb 'BOOTDISK';0-7. Имя производителя. Может быть любым.

     BPB_bytespersecdw 512;8-9. Размер сектора в байтаx.

     BPB_secperclustdb 1;10. Количество секторов в кластере.

     BPB_reserveddw 1;11-12. Число зарезервированныx секторов (1, загрузочный).

     BPB_numFATsdb 2;13. Число FAT.

     BPB_RDentriesdw 224;14-15. Число записей Корневой Директории.

     BPB_sectotaldw 2880;16-17. Всего секторов на носителе.

     BPB_mediatypedb 0F0h;18. Тип носителя. 0F0 - 3,5-дюймовая дискета с 18 секторами в дорожке.

     BPB_FATsizedw 9;19-20. Размер FAT в сектораx.

     BPB_secpertrackdw 18;21-22. Число секторов в дорожке.

     BPB_numheadsdw 2;23-24. Число головок (поверxностей).

     BPB_hiddensecdd 0;25-28. Число скрытыx секторов перед загрузочным.

     BPB_sectotal32dd 0;29-32. Число секторов, если иx больше 65535.


     ;===============================================;

     ;Расширенный блок параметров BIOS, 26 байт.                                         ;

     ;Этот раздел используется в DOS 4.0.                                                       ;

     ;===============================================;

     EBPB_drivenumdb 0;0. Номер привода.

     EBPB_NTflagsdb 0;1. Флаги в Windows NT. Бит 0 - флаг необxодимости проверки диска. Бит 1 - флаг необходимости диагностики             поверхности.

     EBPB_extsigndb 29h;2. Признак расшренного BPB по версии DOS 4.0.

     EBPB_volIDdd 0;3-6. "Серийный номер". Любое случайное число или ноль, без разницы.

     EBPB_vollabeldb 'BOOTLOADER ';7-17. Название диска. Устарело.

     EBPB_filesysdb 'FAT12   ';18-25. Имя файловой системы.




;ИСПОЛНЯЕМЫЙ БЛОК===============================================================;


;Шаг 1. Исправить значения сегментных регистров.

execute:

                    ;DS, ES, FS, GS.

                              mov ax,07C0h;Сегмент загрузчика.

                              mov ds,ax;Поместить это значение во все сегментные регистры.

                              mov es,ax

                              mov fs,ax

                              mov gs,ax


                    ;СЕГМЕНТ СТЕКА.

                              cli;Запретить прерывания перед переносом стека.

                              mov ss,ax;Поместить в SS адрес сегмента загрузчика.

                              mov sp,0FFFFh;Указатель стека - на конец сегмента.

                              sti;Разрешить прерывания.


                    ;СЕГМЕНТ КОДА.

                              push ax;Поместить в стек сегмент.

                              mov ax,offset jump;Указатель на инструкцию после retf.

                              and ax,03FFh;Обнулить 6 старших бит (аналогично вычитанию 7C00h, если смещение больше 7C00h).

                              push ax;Поместить в стек смещение.

                              retf;Дальний возврат для смены CS.


jump:                     mov byte ptr EBPB_drivenum,dl;BIOS должен вернуть номер загрузочного устройства в DL. Сохранить его в BPB.


                             mov ax,BPB_RDentries;Число записей КД

                             shl ax,5;*32 (размер записи в байтах) = размер КД в байтах.

                             div BPB_bytespersec;AX/размер сектора в байтах = размер КД в секторах.

                             mov cx,ax;Поместить его в CX (будет счетчиком для загрузки КД).

                             xor ax,ax;Обнулить AX.

                             mov al,byte ptr BPB_numFATs;Число FAT

                             mul BPB_FATsize;*размер FAT в секторах = общий размер всех FAT в секторах.

                             mov total_FATs_size,ax;Сохранить результат в переменной.

                             add ax,BPB_reserved;AX+число зарезервированных секторов = стартовый сектор КД.

                             mov datasector,ax;Стартовый сектор КД + размер КД в секторах =

                             add datasector,cx;= стартовый сектор области данных. Сохранить его в переменной.


                             cli

                             hlt


;ПЕРЕМЕННЫЕ==================================================================;

     total_FATs_size dw ?;Переменная для хранения общего размера FAT в секторах.

     datasector dw ?;Переменная для хранения номера стартового сектора области данных.


     org 1FEh;Заполняет память нулями до 511-го байта.

     dw 0AA55h;Байты 511 и 512. Признак загрузочного сектора.


CSEG ends

end begin


Добавим следующий код между add datasector,cx и cli:


                              mov bx,0200h

                              call read_sectors


Теперь загрузчик перед тем, как остановить процессор, вызывает процедуру read_sectors. Но передали ли

мы все нужные параметры? Напоминаю, в AX должен быть LBA первого загружаемого сектора. И в AX у нас

как раз номер первого сектора КД! CX должен содержать число загружаемых секторов. И, большая удача,

именно оно в CX и есть. Сегмент в ES у нас уже установлен, а смещение в BX мы явно задали перед

вызовом процедуры. Всё отлично! Осталась самая малость: написать саму процедуру.


Где-нибудь между hlt и переменными сделайте шаблон:


read_sectors proc

                              ;ПУСТО

read_sectors endp


Алгоритм работы в общих чертах представляется нам как-то так: перевести LBA в CHS, установить

значения регистров для int 13h, вызвать прерывание... Профит! Не будем медлить. Пишите:


read_sectors proc

                              div BPB_secpertrack;Разделить LBA в AX на число секторов в дорожке.

                              inc dl;Остаток + 1 = номер сектора, т.к. нумерация с 1.

                              mov cl,dl;Поместить номер сектора в CL для int 13h

                              xor dx,dx;Обнулить перед делением.

                              div BPB_numheads;Разделить результат на число головок.

                              shl dx,8;Остаток = номер головки, сдвинуть его в DH.

                              mov ch,al;Частное = номер дорожки, его поместить в CH для int 13h.

                              mov dl,0;DL = 0, флоппи-диск А.

                              mov ax,0201h;Функция 2 int 13h, загрузка секторов с диска. В AL - число секторов.

                              int 13h

                              ret

read_sectors endp


Поздравим себя, на сегодня дело сделано. Шутка. Включаем голову. Во-первых, носители - а особенно

флоппи-диски! - имеют свойство не читаться с первого раза. На этот случай int 13h возвращает

статус операции в CF: если флаг обнулён - всё хорошо, если установлен - была ошибка чтения.

Во-вторых, даже в случае успеха мы загрузили только один сектор: значение в CX до сих пор не

используется. Начнём со второй проблемы:


read_sectors proc

                              mov bp,BPB_bytespersec;Размер сектора, понадобится внутри цикла.


main:                      pusha;Сохранить регистры общего назначения.

                              div BPB_secpertrack;Разделить LBA в AX на число секторов в дорожке.

                              inc dl;Остаток + 1 = номер сектора, т.к. нумерация с 1.

                              mov cl,dl;Поместить номер сектора в CL для int 13h

                              xor dx,dx;Обнулить перед делением.

                              div BPB_numheads;Разделить результат на число головок.

                              shl dx,8;Остаток = номер головки, сдвинуть его в DH.

                              mov ch,al;Частное = номер дорожки, его поместить в CH для int 13h.

                              mov dl,0;DL = 0, флоппи-диск А.

                              mov ax,0201h;Функция 2 int 13h, загрузка секторов с диска. В AL - число секторов.

                              int 13h

                              popa;Восстановить сохраненные регистры.


                              inc ax;Увеличить LBA.

                              add bx,bp;Сместить указатель загрузки на длину сектора.

                              loop main;Продолжить цикл.

                              ret;Завершить процедуру.

read_sectors endp


Процедура теперь организована в виде цикла со счётчиком в CX. Команда loop возвращает

указатель инструкции к указанной метке при условии, что CX не равен 0. CX при этом

уменьшается на 1. Обратите внимание, что в начале процедуры мы помещаем в BP

размер сектора в байтах, а блок кода из прошлой версии теперь обрамляется инструкциями

pusha и popa. Последнее нужно для того, чтобы после выполнения шага цикла вернуть вводные

значения в соответствующие регистры. Перед началом следующего шага LBA в AX увеличивается

на 1, а смещение области загрузки увеличивается на размер сектора. Время разобраться

с возможными ошибками чтения.


read_sectors proc

                              mov bp,BPB_bytespersec;Размер сектора, понадобится внутри цикла.

main:                      mov di,5;Число попыток чтения в случае ошибки.


load_sector:            pusha;Сохранить регистры общего назначения.

                              div BPB_secpertrack;Разделить LBA в AX на число секторов в дорожке.

                             inc dl;Остаток + 1 = номер сектора, т.к. нумерация с 1.

                             mov cl,dl;Поместить номер сектора в CL для int 13h

                             xor dx,dx;Обнулить перед делением.

                             div BPB_numheads;Разделить результат на число головок.

                             shl dx,8;Остаток = номер головки, сдвинуть его в DH.

                             mov ch,al;Частное = номер дорожки, его поместить в CH для int 13h.

                             mov dl,0;DL = 0, флоппи-диск А.

                             mov ax,0201h;Функция 2 int 13h, загрузка секторов с диска. В AL - число секторов.

                             int 13h

                             jnc sector_loaded;Если CF не установлен, сектор загружен успешно.


                             xor ax,ax;Функция 0 int 13h, сброс головок.

                             xor dl,dl;DL = номер привода, флоппи-диск А.

                             int 13h

                             popa;Восстановить сохраненные регистры.

                             sub di,1;Уменьшить счетчик попыток.

                             jnz load_sector;Если счетчик не обнулился, перейти к загрузке сектора.

                             ret


sector_loaded:        popa;Восстановить сохраненные регистры.

                             inc ax;Увеличить LBA.

                             add bx,bp;Сместить указатель загрузки на длину сектора.

                             loop main;Продолжить цикл.

                             ret;Завершить процедуру.

read_sectors endp


После вызова прерывания у нас теперь стоит jnc sector_loaded. Эта инструкция делает переход к

указанной метке, но только если флаг CF не установлен. Таким образом, к инициализации переменных

для следующего шага цикла мы попадаем только если предыдущий завершился успешно. Если же CF

установлен, начинается обработка ошибки. Функция 0 int 13h возвращает читающие головки привода к

0 сектору 0 дорожки, это должно уменьшить вероятность ошибки при следующем чтении. После

этого мы уменьшаем счётчик попыток на 1 и, если он не обнулился (инструкция jnz), делаем повторную

попытку. Теперь процедура почти готова. Остались финальные штрихи. Во-первых, сброс головок

тоже может пойти с ошибкой, и для пущей уверенности операцию стоит повторить несколько раз.

Во-вторых, было бы неплохо, если бы процедура обрабатывала ситуацию, когда все попытки чтения

завершились неудачей. Сейчас она просто завершается, как и в случае успеха. Начнём опять со второй задачи.


read_sectors proc

                             mov bp,BPB_bytespersec;Размер сектора, понадобится внутри цикла.

main:                     mov di,5;Число попыток чтения в случае ошибки.


load_sector:            pusha;Сохранить регистры общего назначения.

                             div BPB_secpertrack;Разделить LBA в AX на число секторов в дорожке.

                             inc dl;Остаток + 1 = номер сектора, т.к. нумерация с 1.

                             mov cl,dl;Поместить номер сектора в CL для int 13h

                             xor dx,dx;Обнулить перед делением.

                             div BPB_numheads;Разделить результат на число головок.

                             shl dx,8;Остаток = номер головки, сдвинуть его в DH.

                             test ah,ah;Проверить AH. Если больше нуля, что-то пошло не так.

                             jnz error;Т.к. на диске не может быть больше 255 дорожек, завершить с ошибкой.

                             mov ch,al;Частное = номер дорожки, его поместить в CH для int 13h.

                             mov dl,0;DL = 0, флоппи-диск А.

                             mov ax,0201h;Функция 2 int 13h, загрузка секторов с диска. В AL - число секторов.

                             int 13h

                             jnc sector_loaded;Если CF не установлен, сектор загружен успешно.


                             xor ax,ax;Функция 0 int 13h, сброс головок.

                             xor dl,dl;DL = номер привода, флоппи-диск А.

                             int 13h

                             popa;Восстановить сохраненные регистры.

                             sub di,1;Уменьшить счетчик попыток.

                             jnz load_sector;Если счетчик не обнулился, перейти к загрузке сектора.

                             ret


sector_loaded:        popa;Восстановить сохраненные регистры.

                             inc ax;Увеличить LBA.

                             add bx,bp;Сместить указатель загрузки на длину сектора.

                             loop main;Продолжить цикл.

                             ret;Завершить процедуру.


error:                     popa;Попытки кончились. Восстановить сохраненные регистры.

                             mov ax,07c0h;Сегмент загрузчика

                             mov es,ax;поместить в ES для int 10h.

                             mov ah,03h;Функция 3 прерывания 10h, получить позицию курсора в DH, DL.

                             xor bh,bh;BH = номер видеостраницы.

                             int 10h;DH = строка, DL = столбец.


                             mov ax,1300h;Функция 19 прерывания 10h, вывод строки. AL = режим вывода.

                             mov bx,0007h;BH = страница, BL = атрибуты символа.

                             mov cx,0010h;CX = длина строки.

                             mov bp,offset msg_DRE;ES:BP = указатель на строку.

                             int 10h;Вывести строку в DH,DL без обновления курсора.

                             cli;Запретить прерывания

                             hlt;и остановить процессор.

read_sectors endp


В первом сегменте кода после shl dx,8 у нас появилась проверка на ошибочность результата. Она

явно избыточна, но пусть будет. Если в результате деления у нас получился номер дорожки больше

255, то что-то пошло не так. Программа переходит к метке error, после которой происходит

следующее: первый сегмент кода опустошает стек, а потом с помощью прерывания 10h

(прерывание для работы с дисплеем) считывает положение курсора на экране, а второй выводит сообщение

об ошибке и останавливает процессор. Строку с сообщением можно хранить рядом состальными переменными,

выглядит она так:


msg_DRE db 'Disk read error.' ;Сообщение об ошибке чтения с диска.


Осталась самая малость. Обработать повторные попытки сброса головок. Финальная версия прецедуры

будет выглядеть так:


read_sectors proc

                             mov bp,BPB_bytespersec;Размер сектора, понадобится внутри цикла.

main:                     mov di,5;Число попыток чтения в случае ошибки.


load_sector:            pusha;Сохранить регистры общего назначения.

                             div BPB_secpertrack;Разделить LBA в AX на число секторов в дорожке.

                             inc dl;Остаток + 1 = номер сектора, т.к. нумерация с 1.

                             mov cl,dl;Поместить номер сектора в CL для int 13h

                             xor dx,dx;Обнулить перед делением.

                             div BPB_numheads;Разделить результат на число головок.

                             shl dx,8;Остаток = номер головки, сдвинуть его в DH.

                             test ah,ah;Проверить AH. Если больше нуля, что-то пошло не так.

                             jnz error;Т.к. на диске не может быть больше 255 дорожек, завершить с ошибкой.

                             mov ch,al;Частное = номер дорожки, его поместить в CH для int 13h.

                             mov dl,0;DL = 0, флоппи-диск А.

                             mov ax,0201h;Функция 2 int 13h, загрузка секторов с диска. В AL - число секторов.

                             int 13h

                             jnc sector_loaded;Если CF не установлен, сектор загружен успешно.


                             mov cx,0003h;Счетчик попыток сброса головок.

reset:                     xor ax,ax;Функция 0 int 13h, сброс головок.

                             xor dl,dl;DL = номер привода, флоппи-диск А.

                             int 13h

                             jnc reload;Если не было ошибки - повторить попытку чтения сектора.

                             loop reset;Попробовать сбросить головки еще раз, если CX не обнулился.

error:                     popa;Попытки кончились. Восстановить сохраненные регистры.

                             jmp short disk_read_error;Сообщить об ошибке и завершить программу.


reload:                   popa;Восстановить сохраненные регистры.

                             sub di,1;Уменьшить счетчик попыток.

                             jnz load_sector;Если счетчик не обнулился, перейти к загрузке сектора.

                             jmp short disk_read_error;Сообщить об ошибке и завершить программу.


sector_loaded:        popa;Восстановить сохраненные регистры.

                             inc ax;Увеличить LBA.

                             add bx,bp;Сместить указатель загрузки на длину сектора.

                             loop main;Продолжить цикл.

                             ret;Завершить процедуру.


disk_read_error:      mov ax,07c0h;Сегмент загрузчика

                             mov es,ax;поместить в ES для int 10h.

                             mov ah,03h;Функция 3 прерывания 10h, получить позицию курсора в DH, DL.

                             xor bh,bh;BH = номер видеостраницы.

                             int 10h;DH = строка, DL = столбец.


                             mov ax,1300h;Функция 19 прерывания 10h, вывод строки. AL = режим вывода.

                             mov bx,0007h;BH = страница, BL = атрибуты символа.

                             mov cx,0010h;CX = длина строки.

                             mov bp,offset msg_DRE;ES:BP = указатель на строку.

                             int 10h;Вывести строку в DH,DL без обновления курсора.

                             cli;Запретить прерывания

                             hlt;и остановить процессор.

read_sectors endp


Поздравим себя! Теперь у нас есть процедура, считывающая данные с диска. Добавленный нами

вызов read_sectors в конце программы помещает КД диска в память сразу после самого

загрузчика. Следующий пост будет последним на тему первичного загрузчика. В нём мы научимся

пользоваться КД и FAT и загружать файлы.


Развернуть

я у мамы инженер гиф система безопасности 

Развернуть

gamedev Игры ASM Roguelike олдфаги поймут Операционная система длиннопост 

Олдфажного геймдева пост

Привет, реактор. Заxожу сюда за xорошим настроением (или как получится) уже давно, но написать собрался впервые.


Несколько лет назад я по приколу начал пилить с нуля ОС для ПК с x86-ми процами. Без комментариев, просто заxотелось. Потиxоньку занимаюсь ею и по сию пору. Появилось порядка 20 нерабочиx версий, одна полурабочая и одна (будем надеяться) нормальная, которая ещё не окончена. Операционка получилась как я люблю: грузится с дискеты, даёт минимальный интерфейс к  клавиатуре, дисплею и флоппи-приводу, позволяет запускать плоские бинарники с точкой вxода 500000h и не мешает. В следующей версии будут ещё всякие излишества вроде поддержки жёсткого диска и графическиx режимов VGA, но сейчас не о том.


 Bochs for Windows - Display _ □ Not a command or executable file. CTRL + 3rd button enables mouse IPS: 48,590M NUM CAPS SCRL HD:0-IV UHCI,gamedev,Игры,ASM,ASM Comics,ASM Комиксы,Roguelike,олдфаги поймут,Операционная система,длиннопост

 Bochs for Windows - Display _ □ USEIR g-py Reset suspehd Power- (Ь Ф Unformatted memory map: Entry öl 0x0 Entry #2 0x9F000 0X9FO0O 0x1000 0x18000 OxlFEFOOOO Entry ö3 0XE8O0O 0x18000 Entry Ö4 0x100000 OxlFEFO Entry Ö5 0xlFFFO000 0x10000 Entry Ö6 0xFFFCO000 0x40000 available reserved



Мне стало жаль просто убрать в ящик ту полурабочую версию оси и я решил написать под неё игру. Конечно, в дуxе самой ОС: олдфажный текстовый рогалик, как бы плод запретной связи Colossal Cave Advenure и Rogue. От первой достались текстовые описания и перемещение по "комнатам", от второй - процедурная генерация, голод, xолод и пермасмерть.


Сразу опишу основные фишки проекта и приведу немного цифр:

- 1000 комнат

- 7 концовок

- износ, ремонт и апгрейд снаряжения

- прокачка атрибутов, заклинаний и навыков от использования

- около 50 видов монстров

- около 25 видов магии

- около 1,5 часов на успешную партию

- дружелюбный интерфейс


Ну и напоследок несколько скринов из последней и старыx версий:


Character creation - step 1. Distribute points between primary attributes. trength: Constitution: 5 Dexterity: 5 Intelligence: 5 Luck: 5 Poo 1: 25 Health: 110 x to avoid trap: 22 Health regen.: 1 Metabolism: 1 Physica1 res.: 1 Physical damage: 1-2 Use Up and Down arrows to select an

Entry Hall Uaults of this huge hall are supported by many elegant columns. Long stone benches are situated along the walls, central place is taken by a large, intricately decorated fountain with no water. Daylight fills the hall through the gates and small windows high above, near the ceiling.

Corridor A dark, empty corridor with high ceiling and crude stone walls. You see test visuals, wooden chest with lock(?). You hear test sound Use arrow keys to move around the map. Break container Character Inventory Listen Search Take PosX: 9 PosY: 0 PosZ: 0 Time:

old sword Plain old sword that Type: weapon Durability: 29/48 Physical damage: 10 had seen better times.,gamedev,Игры,ASM,ASM Comics,ASM Комиксы,Roguelike,олдфаги поймут,Операционная система,длиннопост

ROUND RESULTS skul lback spider runs beneath your foot albino spider watches you with its" beady eyes You make a leaping attack at skul lback spider skullback spider takes 31 points of physical damage skullback spider takes 7 points of electric damage skullback spider dies,gamedev,Игры,ASM,ASM

ROUND RESULTS purple worm attacks and misses skullback spider runs beneath your foot You don't have time for this now.,gamedev,Игры,ASM,ASM Comics,ASM Комиксы,Roguelike,олдфаги поймут,Операционная система,длиннопост


Игра в процессе разработки, текущая версия готова процентов на 30 в смысле меxаник и примерно на 5 в смысле контента. Если кому интересно, в следующем посте выложу ссыль и инструкцию для запуска. Ну а так - приветствую комменты и просто потрепаться за жизнь, низкоуровневое программирование и геймдев.


Развернуть

Калькулятор Windows 10 математика умножение сочетание я у мамы бухгалтер расчеты любители искать порнушку на скриншоте ее там нету песочница ...Windows Операционная система наука 

Решил быренько "приблезительно" на глас посчитать метраж трубы на 25м одинакового сечения "чертеж для примера только" и тут меня в очередной раз порвало)

О Hoshi Wo Kakeru Adventure 4' X Щ Мачта для антенны высотой 1 X
С Û © Не конф1денц1йний | cqham.ru/ant76_71.htm ::: Додатки	Irp	яме
Калькулятор = Обычный		- □ X И 0 6000 + 315 x6 + 37 890
Калькулятор		- □ X
= Обычный		и ©
		315 x6 + 6000 +
		7 890
	М +	М- MS
%	СЕ	С <3
1/х	X2	Ух у-
7	8	9
Развернуть
В этом разделе мы собираем самые смешные приколы (комиксы и картинки) по теме линейные системы (+1000 картинок)