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

cx 7

»

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



omron cx-programmer плк plc Traffic Light светофор контроллеры плк длиннопост песочница 

Доброго времени суток реактор. Пришёл с крупной проблемой, я тупой. Но надеюсь это временно.

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

Мои мучения в понимании того как собрать правильно схему работы Светофора происходят уже несколько недель, почти каждый день я сажусь и пытаюсь выполнить задание которое мне дали в вузе. Я задавал аналогичные вопросы на 3-ёх разных форумах, мне советовали множество вариантов исправления моей проблемы.

Как работает светофор? По очереди загораются Красный, красный и жёлтый, зелёный, жёлтый.

За всё время в попытках выполнить задание у меня появилось несколько его версий.

Первая версия до того как мне подсказали как он правильно должен работать.

На данный момент светофор функционирует нормально: лампочки загораются в правильном порядке - сначала зелёная, затем жёлтая, и в конце красная, после чего схема повторяется. Однако данное решение не соответствует требованиям, так как лампочки должны загораться в обратном порядке: сначала красная, затем жёлтая, и в конце зелёная. Я перенёс контакт таймера 3 с ранга 1 на ранг 2, и теперь схема застряла в одном месте. Сигнал, идущий с зелёного света, переходит сразу к жёлтому и застревает между ними, не достигая зелёного. Я попробовал десяток комбинаций таймеров, но так и не смог добиться правильной работы программы. 

Сколько я только не перепробовал позиций контактов, я ставил из несколько шт в одном месте с разными адресами, смотрел ролики на YouTube которые в большинстве своём записаны узбеками и в малом кол-во другими национальностями. Схемы в каждом видео разные, я пробовал строить эти схемы, некоторые даже не работали у меня. Я не увидел чтобы хоть одна из этих схем выполняла правильный цикл программы. Потом я пытался несколько раз переделать схему по советам с форумов, это мне не помогло. Файл Светофор 3.

Вторая версия. Так же мне подсказали что есть готовый пример Светофора (C:\Program Files (x86)\OMRON\CX-One\CX-Programmer\Examples) я попробовал использовать его, и переделал свой вариант чтобы он был похож на неё, но у меня всё равно не получается заставить схему работать. Файл Traffic Light My. В этой версии программы лампочки не идут сверху схемы как изначально у меня было, они расположены внизу. Я попытался разместить лампочки сверху но из этого мало что получилось.

Третья версия мне показали Руководство по Cx-programmer 5.0 на странице 18 (71) в котором тоже был пример выполненния программы, и угадайте что? После завершения сбора этой схемы с нуля я понял что собрал схему tutorial. Теперь я знаю при сборке схемы можно использовать Локальные символы которые прописываются отдельно и потом с помощью них указываются адреса контактов, катушек, таймеров и т.д. Я снова попытался поставить на те же места лампочки, также создал новые локальные символы подключил к лампочкам. Светофор по методичке Cx-programmer

В процессе всего поиска информации чего мне только не советовали:

* Переставить выходы, а не таймеры;

* Давали ГОСТ Р 52289-2019, раздел 7.5 "Режимы работы светофоров"

* Добавить контакт в ранг 0 под контакт 1. Сколько контактов я не добавлял и менял их значения это мало чем помогло.

* Советовали использовать ROL-ROR и Set Reset тут я вообще не понял ничего. 

* Скидывали ещё видео

, схема выполненая в другой программе и ничего похожего в Cx-programmer я не нашёл.

* Так же я сам находил видео

 и Часть 16 тоже другая программа не похожая на Cx-programmer.

" 1 человек с форума 3 посоветовал. Разбить свою задачу на две подпрограммы которые по условиям не могут работать одновременно. В одной подпрограмме зажигаете зелёный, в другой красный. Скинул так же готовый файл и там схема стала ещё более запутанной.

Буду неизмеримо благодарен за оказаную помощь в этом вопросе.

КУПОН НА 1 помощь,omron,cx-programmer,плк,plc,Traffic Light,светофор,контроллеры плк,длиннопост,песочница
Развернуть

Cyberpunk 2077 Игры Windows 7 Windows Операционная система 

В Cyberpunk 2077 можно будет сыграть на Windows 7

В интервью PCGamesHardware Марцин Голлент, ведущий программист графики в CD Projekt RED, раскрыл некоторые новые интересные технические подробности о Cyberpunk 2077. По словам разработчика, Cyberpunk 2077 будет поддерживать только API DirectX 12. Более того, он будет работать только на Windows 7 и Windows 10.


Когда его спросили об операционных системах ПК, для которых будет доступен Cyberpunk 2077, Голлент сказал:

«Благодаря внедрению поддержки DX12 для Windows 7 SP1, представленной Microsoft в прошлом году, игра будет работать на этой системе. Мы проводим и будем продолжать тестировать Cyberpunk 2077 на Windows 7, пытаясь сгладить любые крайние ситуации, которые могут возникнуть. К сожалению, Windows 8 не получила свой вариант библиотек DX12».


Так что да, те, кто все еще использует Windows 8, не смогут поиграть. Важно отметить, что не будет никакого резервного API DX11.

Голлент также поделился некоторыми подробностями о DX12 Ultimate. Как заявил разработчик, игра будет работать с любым графическим процессором DX12. Однако те, кто поддерживает дополнительные функции DX12 Ultimate, смогут получить некоторые дополнительные улучшения.


«Что касается DX12 Ultimate, Cyberpunk 2077 будет отлично работать со всеми DX12-совместимыми графическими процессорами. Функция Ultimate позволяет нам делать больше, если это позволяет аппаратное обеспечение. Мы выбрали DX12 по двум основным причинам. Во-первых, это стандартный API для платформ Xbox. С появлением игры для Xbox One мы, естественно, хотели, чтобы она была реализована как можно скорее. Во-вторых, это место рождения DXR, и, учитывая, что мы планировали инвестировать в DXR очень рано, это сделало выбор в пользу DX12 довольно простым».
Развернуть

siemens мобильные телефоны 

Siemens CX 65 (Concept 2019).

SIEMENS 2004 2019CONCEPT,siemens,мобильные телефоны
siemens,мобильные телефоны
siemens,мобильные телефоны
siemens,мобильные телефоны
siemens,мобильные телефоны

Развернуть

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

Не очень понятно функциональное применение этих... хм пазов. Ну хоть дизайн неординарный.
Barboss3 Barboss314.08.201910:52ссылка
+31.4
можно будет тип слинг прицепить чтобы на шее носить
theplugstar theplugstar14.08.201910:53ссылка
+6.6
Или в жопе.
rokhz rokhz14.08.201911:46ссылка
-1.1
О, как в старые добрые времена.
Micromancеr Micromancеr14.08.201911:50ссылка
+55.8

anon 

100000111101000011010010000111000100001111011000001000011100010000110111100000100001111011000011000010001000001100000100001111111000011100010000110100100001111101000100000010000110000010000011111100010000001000011100010000110111100001111011000011000010000110010100001100001000011100110001000010100001101011000100000110001001100100000100001110101000100001010000111110100001100000
Развернуть
Комментарии 2 14.07.201804:56 ссылка -6.2

Дрочибельные мемы трудовик NSFW 

WSIUWL / / d U I or шпшипмм ctrfi: Hi a 8Æ3. ? 5Hï&ml+u. ' у^£бШ1у& nJMbLUL.- 1 CfáfbJSS ItyjfOL 6.,Дрочибельные мемы,трудовик,NSFW
Развернуть

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

 Ui or > ' / шгмштигл. Omh: 44iШЛЪЧ~каъ и hUfjCML/. ЦШ üWi.. {Si yhhjjoi. 3 t h 'LbViUß' — 7 ‘ t «f Ш • УпУш/L ¿y S^C-CX-ist, /£ c*^ S % 2- tfr YrülUd - / -yr r/ 1 Taa ! m
Topec Topec15.04.202419:58ссылка
+39.4

geek video самый маленький квадрокоптер песочница Кликабельно 

TRNDlabs представила SKEYE Pico Drone - самый маленький в мире квадрокоптер.

Фирма TRNDlabs решила заявить о себе как создателе уникальных БПЛА и приложить усилия, чтобы её имя ассоциировалось с крошечным квадрокоптером, обладающим рекордными габаритными размерами. Анонсированная модель SKEYE Pico Drone по-настоящему удивляет своей миниатюрностью и весом — корпусом 2,2 × 2,2 × 1,9 см, суммарная масса которого равняется 7 граммам.

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

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

Урок ОСдева №7: первичный загрузчик, финал.

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

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

программы-загрузчика по адресу 07C0h:0200h. План действий на сегодня:


-Найти в КД номер первого кластера файла.

-Загрузить первый кластер.

-Следуя по цепочке записей в FAT, загрузить остальные кластеры.


Перед тем, как кодить дальше, давайте  разберёмся, что такое КД и как её использовать для

поиска файлов*.


По сути корневая директория в FAT12 - это таблица, в которой каждому файлу или

поддиректории соответствует одна 32-байтная запись. Давайте посмотрим, что в ней есть.


Байты 0-10: имя файла в формате 8:3. Этот формат подразумевает, что имя файла занимает

ровно 8 байтов, а расширение - 3. Если имя файла меньше 8 символов, оно дополняется

пробелами: так, файл 'loader.bin' в КД будет проходить под именем 'LOADER  BIN'.


Байт 11: атрибуты записи. Набор флагов, позволяющий придать записи особые свойства.

          00000001b = только для чтения

          00000010b = скрытый

          00000100b = системный

          00001000b = метка раздела

          00010000b = директория

          00100000b = архив

          00001111b = LFN (long file name), запись имеет особый формат, поддерживающий длинные

                              имена файлов.


Байт 12: зарезервирован для Windows NT.


Байт 13: время создания в десятых секунды (почему-то 0-199 согласно OSDev Wiki).


Байты 14-15: время, когда был создан файл. Младшие 5 бит - секунды/2 (то есть при интерпретации

значения, например, для вывода на экран, эту часть надо умножать на 2). Следующие 6 - минуты.

Последние 5 бит - часы.


Байты 16-17: дата создания файла. Примерно та же история. День(0-4), месяц(5-8), год(9-15).


Байты 18-19: дата последнего доступа в том же формате, что и дата создания.


Байты 20-21: старшие 16 бит номера первого кластера файла. В FAT12 и FAT16 не используется.


Байты 22-23: время последнего изменения в том же формате, что и время, когда был создан файл.


Байты 24-25: дата последнего изменения в том же формате, что и дата создания.


Байты 26-27: младшие 16 бит номера первого кластера файла.


Байты 28-31: размер файла в байтах.

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

стартового кластера (старшая половина в FAT12 не используется). Вырисовывается в общих чертах

алгоритм поиска файла? Если нет, я помогу:


1. Переходим к началу КД

2. Считываем имя записи

3. Сравниваем имя записи с именем искомого файла

4. Если имена совпали, файл найден, SUCCESS!

5. Записи кончились?

6. Если кончились - файла нет, аварийно завершаемся

7. Переходим к следующей записи

8. goto 2

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

об этом пользователя и свернуть выполнение загрузчика. Я решил, начиная с этого поста, не

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

конце. Это позволит вместить в пост больше полезной информации, не растягивая его до

нечитабельных размеров. А теперь давайте выполним наш поисковый алгоритм в коде. После

call read_sectors пишите:


                   mov cx,BPB_RDentries

                   mov di,0200h

                   mov si,offset fname

                   mov bp,si


next_entry:   mov ax,cx

                   mov bx,di

                   mov cx,11

                   rep cmpsb

                   mov si,bp

                   mov di,bx

                   mov cx,ax

                   je load_FAT

                   add di,32

                   loop next_entry


                   mov ah,3

                   xor bh,bh

                   int 10h


                   mov ax,1300h

                   mov bx,0007h

                   mov cx,22

                   mov bp,offset fname

                   int 10h


                   cli

                   hlt

Что всё это значит? В строчке mov cx,BPB_RDentries мы устанавливаем счётчик основного

цикла. Напоминаю, что в переменной BPB_RDentries у нас хранится число записей корневой

директории. 0200h - смещение загруженной в RAM КД. В SI мы помещаем смещение строки с

именем искомого файла. Кстати, впишите в переменные fname db 'LOADER  BIN'. После этого

мы сохраняем это же смещение в регистре BP. Это может быть пока неочевидно, но позже вы

поймёте, зачем.


Следующий блок кода, начинающийся с метки next_entry, - это собственно цикл просмотра

записей КД и сравнения имён. Первым делом мы сохраняем счётчик цикла и смещение текущей

записи. Счётчик сохраняем потому, что будет вложенный цикл, а смещение - потому, что

строковые инструкции вроде cmpsb изменяют значения регистров SI и DI. Кстати, теперь вам

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


mov cx,11 - установка счётчика вложенного цикла. Имена в FAT12 хранятся в формате 8:3,

значит, нам нужно сравнить две строки по 11 символов. Надеюсь, тут вопросов нет?

Инструкция cmpsb сравнивает значения двух байтов (в нашем случае символов), находящихся

в DS:SI и ES:DI. Префикс rep повторяет инструкцию, пока не обнулится счётчик в CX.

Далее мы восстанавливаем счётчик основного цикла в CX, смещение текущей записи в DI и

смещение строки с именем файла в SI. В старых версиях здесь у меня были пары инструкций

push/pop, но потом я подумал, что трансфер из регистра в регистр быстрее, чем обращение

к стеку, и поменял. Никогда не вредно сэкономить пару циклов.


Если в результате rep cmpsb все символы совпали, в регистре флагов будет установлен бит

ZF. Команда je load_FAT выполняет переход к метке load_FAT если флаг ZF установлен.

В случае если строки не совпали, мы переводим DI к следующей записи в КД и продолжаем

цикл командой loop next_entry. Тут бы можно было и закончить, но нужно обработать

отсутствие файла. С этим набором инструкций мы уже знакомы по предыдущему посту.

Первый блок возвращает положение курсора в DH,DL, а второй выводит от этой позиции

сообщение. Отличается только само сообщение. Вместо 'Disk read error.' мы выводим строку

с именем файла. Внимание, тут небольшой хак. Идея в том, чтобы вывести следующий текст:

'{filename} not found!'. Вызвать вывод строки два раза, но зачем? Если поместить в

разделе переменных текст ' not found!' сразу после переменной fname, а при вызове int 10h

указать в CX не 11 символов, а 22, то выведется сначала имя файла, а потом ' not found!'

Конечно же, этот текст обязательно должен быть сразу после fname. Добавьте строчкой ниже

db ' not found!' После этого останавливаем процессор парой команд cli и hlt. Не так-то

сложно, да? Впрочем, файл ещё нужно загрузить.


Для этого нам нужно будет загрузить в память FAT и разобраться, как ею пользоваться.

Давайте начнём с первой задачи, она чисто техническая и не требует умственного напряжения.

После hlt набирайте:


Load_FAT:          mov ax,[di+26]

                         mov cluster,ax

                         mov ax,BPB_reserved

                         mov cx,total_FATs_size

                         mov bx,BPB_RDentries

                         shl bx,5

                         add bx,0200h

                         mov FAT_offset,bx

                         call read_sectors

В строчке mov ax,[di+26] мы считываем из записи КД номер первого кластера файла, а затем

сохраняем его в переменной cluster. Далее, мы помним, что FAT у нас идут сразу после

зарезервированных секторов, поэтому в AX помещаем BPB_reserved. В CX у нас будет число

секторов, которое надо загрузить, то есть total_FATs_size. Загружать FAT будем сразу после

КД, то есть в 07С0h:0200h+размер КД. Размер КД = число записей КД*размер записи (32 байта).

Помещаем в BX число записей (BPB_RDentries), умножаем на 32 (shl bx,5 эквивалентно умножению

на 32, но выполняется быстрее) и добавляем 0200h. Готово! Сохраняем на будущее в переменной

FAT_offset (кстати, объявите её рядом с прочими) и вызываем read_sectors.


А теперь время вернуться к теории. Что такое FAT? Не поверите, но это тоже таблица, и её

структура ещё проще, чем у КД. Каждая запись в FAT соответствует кластеру на диске. FAT

можно назвать оглавлением диска (украл с OSDev Wiki). Кластер может быть свободен, занят

частью файла, зарезервирован ОС или испорчен. Если кластер хранит часть файла, то его

запись в FAT будет содержать номер следующего кластера файла. Понятно? Зная номер первого

кластера файла, мы можем загрузить его в память, потом заглянуть в FAT, найти нужную запись

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

всегда, есть большое "НО"! Размер записи в FAT12 - 12 бит. Мы не можем оперировать

12-битными ячейками. Мы можем считать 8 или 16. То есть, если мы загрузим в AX начало FAT,

то в регистре окажется первая запись и часть второй. А если сдвинемся на один байт, то

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

наглядности. В верхней строчке будет часть FAT, разделённая на записи, а в нижней она же,

но поделенная на 8-битные куски.


0 0 0 1 0 1 1 1 0 0 1 0|0 1 1 1 0 0 1 0 1 0 0 0|0 0 1 0 0 1 0 0 0 1 1 1          3 Записи.

0 0 0 1 0 1 1 1|0 0 1 0 0 1 1 1|0 0 1 0 1 0 0 0|0 0 1 0 0 1 0 0|0 1 1 1         4,5 байта.


Решение в том, чтобы, считывая каждый нечётный кластер, сдвигать значение на 4 бита вправо, а

у чётного - обнулять 4 старших бита. Зная всё это, давайте писать код:


                             push 0050h

                             pop es

                             xor bx,bx

read_cluster:           mov ax,cluster

                             sub ax,2

                             movzx cx,BPB_secperclust

                             mul cx

                             add ax,datasector

                             call read_sectors

                             mov ax,cluster

                             mov si,ax

                             shr ax,1

                             add si,ax

                             add si,FAT_offset

                             mov dx,[si]

                             mov ax,cluster

                             test ax,1

                             jnz odd_cluster

                             and dx,0000111111111111b

                             jmp short done

odd_cluster:           shr dx,4

done:                     mov cluster,dx

                             cmp dx,0FF7h

                             jb read_cluster

Финальный рывок. Первое, что мы делаем - устанавливаем сегмент для загрузки файла. Так как

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

в 0000h:0000h, но первые 1280 байт заняты важными вещами, о которых поговорим позже.

Ближайший свободный участок RAM - 0050h:0000h (или 0000h:0500h, это тот же самый адрес

если вы вдруг забыли правила адресации сегмент:смещение). Обнуляем BX, так чтобы пара

ES:BX указывала на 0050h:0000h. Считываем в AX номер первого кластера файла. Дальше мы

вычитаем 2 из этого номера. Зачем? Затем, что значения 0 и 1 в FAT зарезервированы и не

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

значение. Да, это идиотизм.


Загружать будем не сектор, а кластер (что в нашем случае одно и то же, но всё-таки),

поэтому в качестве числа секторов помещаем в CX переменную BPB_secperclust и на неё же

умножаем номер кластера. AX*CX в данном случае дадут нам номер первого сектора нужного

кластера. А так как кластеры в FAT начинают считаться от начала области данных,то для

абсолютного значения добавляем к AX datasector. Готово. Вызываем read_sectors и загружаем

первый кластер файла в RAM.


Дальше будет немножко математической магии, объяснять которую я не буду. Если интересно -

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

смещение записи кластера внутри FAT = 3/2 номера кластера. Значит, берём в AX номер

кластера, его же помещаем в SI, делим AX на 2 и прибавляем к SI. Вуаля, смещение

записи от начала FAT найдено. Добавляем к нему смещение FAT_offset и считываем в DX

значение записи.


Теперь надо проверить, чётная ли запись. Для этого опять берём в AX номер кластера и

делаем сравнение с 1. Если флаг ZF не установлен (то есть 0 бит значения равен 1),

значит, номер записи - нечётный, переходим к odd_cluster и сдвигаем значение вправо на

4 позиции. Если чётный - делаем логическое "И" с маской 0000111111111111b и обнуляем

тем самым 4 старших бита. Теперь у нас есть содержимое нужной записи без всяких

посторонних хвостов, то есть номер следующего кластера. Сохраняем его в переменной

cluster. Дальше у нас идёт сравнение с номера с числом 0FF7h. Дело в том, что,

начиная от этого значения в FAT идут специальные коды, которые могут означать конец

файла, испорченный сектор и т.д. Для нас это значит, что если в качестве номера

кластера мы получили 0FF7h или больше, продолжать загрузку не имеет смысла. Поэтому

продолжаем цикл только если DX меньше 0FF7h. Я умышленно оставляю здесь дыру и

предлагаю всем заинтересованным попытаться самостоятельно сделать обработку ошибки,

связанной с битым кластером (код 0FF7h). Код конца файла, кстати, 0FF8h. Вся необходимая

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


А мне остаётся только добавить в конце три строчки:


                    push 0050h

                    push 0000h

                    retf

Этот набор команд мы уже помним из старых постов. Помещаем в стек сегмент, потом

смещение, и передаём управление загруженному файлу командой retf. Поздравим себя!

Первичный загрузчик готов. Да, он умеет немного, но и задача у него всего одна:

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

скомпилируете файл без инструкций org 1FEh и dw 0AA55h, то увидите, что программа

занимает всего 447 байт. Значит, у нас есть в запасе ещё 63. Как раз должно

хватить на проверку успешного считывания кластеров. У меня вместе с ней вышло 497

байт. Можете подсмотреть в приложенном файле, хоть это и неспортивно. Если вы

поместили загрузчик на дискету и получили в bochs (или на реальной машине) вот такой

экран, то всё работает как надо!


Plex86/Bochs UGABios (PCI) current-cvs 08 Jul 2014 This UGA/UBE Bios is released under the GNU LGPL Please visit : . http://bochs.sourceforge.net . http ://www.nongnu.org/vgab ios Bochs UBE Display Adapter enabled Bochs BIOS - build: 07/10/14 $Revis ion: 12412 $ $Date: 2014-07-10 09:28:59


Чистая дискета:

https://drive.google.com/file/d/1Bold4ds8oEruHQ7fJZKHglVo7A2Vc5MR/view?usp=sharing


Листинг:

https://drive.google.com/file/d/1Q5EtKX5kyF4MWcBeD8a6Jz5cPtqZja9C/view?usp=sharing


Bochs:

https://drive.google.com/file/d/16k2Gpr7oPSekq4rAhmtBV0IPnIteDLlE/view?usp=sharing


* FAT поддерживает вложенные директории, и они ничем принципиально не отличаются

от корневой, так что всё нижеизложенное касается и их. 


Развернуть

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

Урок ОСдева №5: подготовка к работе с файловой системой FAT12.

В прошлый раз мы инициализировали сегментные регистры и обеспечили загрузчику безопасную среду

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

поподробнее ознакомиться с её структурой. В FAT12 пространство носителя можно разделить на

несколько областей. Они могут быть разного размера, но идут всегда в следующем порядке:


ЗАГРУЗОЧНЫЙ СЕКТОР - ЗАРЕЗЕРВИРОВАНО - FAT - КД - ОБЛАСТЬ ДАННЫX


Наша задача - вычислить начало и размер каждой области на нашем носителе. Эта информация понадобится

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

а не байтами. То есть, когда я пишу "размер", я имею в виду количество секторов, занятыx

областью.


Загрузочный сектор - место, где обитает наша программа. Это всегда сектор

номер 1 на носителе, и занимает он ровно 1 сектор. Было несложно.


Далее, зарезервированныx секторов у нас нет. Вернее, есть один, загрузочный. Общее число

зарезервированныx секторов включая загрузочный можно найти в переменой BPB_reserved блока

параметров BIOS.


FAT, таблица распределения файлов. Будет чуть сложнее. Размер FAT в секторах xранится в переменной

BPB_FATsize. Но, как я уже писал ранее, часто на диске может быть дублирующая FAT на случай

повреждения данныx. Количество FAT на диске указано в переменной BPB_numFATs. Для вычисления

общего размера всех FAT на диске нам нужно умножить размер FAT на число FAT.


Дальше у нас идёт корневая директория. Это набор записей о размещении файлов. Размер записи КД

в FAT12 - 32 байта. Количество записей указано в переменной BPB_RDentries. Берём размер записи

и умножаем на число записей. Всё? Нет. Так мы получим размер в байтах, его нужно перевести

в секторы. Для этого резльтат делится на размер сектора в байтах, который хранится в переменной

BPB_bytespersec.


Вот теперь всё. Вспомним, как выглядела программа в конце прошлого поста:


.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_OEMname db 'BOOTDISK'          ;0-7. Имя производителя. Может быть любым.

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

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

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

          BPB_numFATs db 2                          ;13. Число FAT.

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

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

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

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

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

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

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

          BPB_sectotal32 dd 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 stop               ;Указатель на инструкцию после retf.

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

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

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


stop:            cli

                   hlt


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

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


CSEG ends

end begin



Как всегда я написал максимально подробные комментарии к каждому действию. Теперь после retf добавьте

следующий код вместо cli и hlt:


stop:           mov byte ptr EBPB_drivenum,dl


                  mov ax,BPB_RDentries

                  shl ax,5

                  div BPB_bytespersec

                  mov cx,ax

                  xor ax,ax

                  mov al,byte ptr BPB_numFATs

                  mul BPB_FATsize

                  mov total_FATs_size,ax

                  add ax,BPB_reserved

                  mov datasector,ax

                  add datasector,cx


                  cli

                  hlt



Давайте разбираться. С инструкцией mov мы уже знакомы, так что первая строка должна быть понятна:

команда помещает содержимое регистра DL в переменную EBPB_drivenum. Но что за byte ptr?

Это префикс смены разрядности. Так как мы работаем в 16-битном режиме, TASM предполагает, что

и разрадность всех ипользуемых ячеек памяти - 16 бит. Если мы хотим работать с 8-битной

переменной, её разрядность нужно указать вот таким способом.


И зачем вообще мы сохраняем DL как номер привода, с которого была загружена программа? Дело в

том, что по идее BIOS должна вернуть его в DL. В принципе, доверять этому значению не стоит,

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


Далее команда mov ax,BPB_RDentries считывает в AX число записей в корневой директории,

а команда shl ax,5 умножает его на 32. Команды shl и shr сдвигает биты числа влево и, соответственно,

вправо (сокращение от shift left и shift right). Сдвиг числа влево на 1 эквивалентен умножению

на 2. Сдвиг на 5 эквивалентен умножению на 32. На старых процессорах сдвиг выполнялся быстрее,

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


div BPB_bytespersec делит результат предыдущей операции на число байтов в секторе. Вы наверное

заметили, что регистр ax в команде нигде не указан: операция DIV всегда выполняется на этом

регистре. В результате деления мы получаем чсло секторов, которые занимает КД. mov cx,ax

сохраняет результат в cx, а xor ax,ax обнуляет ax, выполняя на нём "исключающее или" с ним же.


mov al,byte ptr BPB_numFATs считывает в регистр al количество FAT на диске. Кстати! Регистров

al и dl не было в списке, который я приводил на прошлом уроке. Сейчас поясню.

Четыре регистра общего назначения ax,bx,cx и dx делятся на две 8-битные половины.

ax на al и ah, bx на bl и bh, ... l в данном слуае значит low, то есть младшие 8 бит.

h, соответственно, старшие high. Так вот, получив число FAT в al, мы умножаем его на

BPB_FATsize (размер FAT в секторах). Обратите внимание, операция умножения выполняется

на всём регистре ax, а значение мы поместили в al. Для этого мы и обнуляли ax операцией

раньше. Получив в результате общий размер всех FAT на диске, сохраняем его в переменной

total_FATs_size.


Добавив к ax BPB_reserved, получим общий размер FAT и зарезервированных секторов.

Сохраним его в переменной datasector, а затем прибавим к ней cx, в котором хранится

размер КД. Теперь в datasector хранится общий размер КД, FAT и зарезервированных

секторов, то есть номер сектора, с которого начинается область данных. Обратите внимание,

с точки зрения быстродействия правильнее было бы сначала сложить ax и cx, а уже потом

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

времени, чем операции надрегистрами. Зачем я сделал именно так, станет понятно в

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

в дальнейшем, и познакомились в общих чертах со структурой FAT12.


В качестве ДЗ предлагаю самостоятельно объявить использованные нами переменные total_FATs_size и

datasector. Обе 16-битного формата. Переменные можно объявлять где угодно до тех пор, пока они не

встревают в исполняемый код. Например, можно вставить между dw 0AA55h и CSEG ends

Развернуть

новости наконец-то шум 

В Подмосковье запретили делать ремонт по выходным

Ремонты, перепланировки и прочие шумные работы в жилом секторе в Подмосковье теперь можно проводить только в будни - с 9 утра и до 7 вечера. В воскресенье и праздничные дни шуметь запрещено круглосуточно. Соответствующие поправки в закон о тишине в окончательном чтении приняли депутаты Мособлдумы.

Ранее нарушать покой жителей области нельзя было с 9 вечера до 8 утра в будние дни, с 10 вечера до 10 утра в выходные и с 13.00 до 15.00 ежедневно, если речь шла о шумных работах внутри жилых помещений.

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

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

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

Источник: https://rg.ru/2016/12/01/reg-cfo/v-podmoskove-zapretili-delat-remont-po-vyhodnym.html
новости,наконец-то,шум
Развернуть

#Приколы для даунов VR отзыв 

Рго(2021) ОООУ1$® \ •н Моя лучшая покупка в этом году! О 18 а £ 1299 просмотров Купил два месяца назад простенькие УЯ очки и не могу нарадоваться. Поймите правильно, я ни разу не геймер, иначе полноценный шлем купил бы. Мне этот девайс необходим для намного более важных дел, нежели в гульки
Развернуть

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

266775777 26677577720.04.202314:27ссылка
+112.8
В этом разделе мы собираем самые смешные приколы (комиксы и картинки) по теме cx 7 (+1000 картинок)