Может есть хороший форум на русском?

Everything you can't fit into other forums
user123
Posts: 11
Joined: Wed Jul 13, 2022 10:51 am

Может есть хороший форум на русском?

Post by user123 »

. Приветствую всех, решил попробовать поучаствовать в жизни этого форума.
. Начну со своего личного вычислителя (персонального компьютера). Это "Pentium-3 Katmai 500" на плате "ASUS P3B" "Slot 1", жёсткий диск около 40 ГиБ (Гибибайт, 1 ГиБ равен 1024^3 байт). ОС "Windows 95 OSR2.5" и "Linux debian 6.0.10 squeeze".
. Уже пробовал выступать на других форумах, но скатывался в дно. Приведу пример (О - оппонент):
Я: фирма intel решила пустить прерывания от времямера (таймера) с частотой около 18,2 Гц. Что вообще непонятно, так как для счёта времени приходится городить дробную арифметику. И это лишь верхушка айсберга искусственных проблем "wintel".
О: на материнской плате стоит кварц 32768 Гц. Интересно, зачем он там?
Я: автономная система часов от батарейки используется только при выключенном вычислителе (компьютере). При включении "BIOS" считывает начальное время из медленной памяти автономных часов в быстрое ОЗУ и дальнейший счёт ведёт обработчик прерывания, не занимая системную шину.
О: нет, процессор не используется для счёта времени.
Я: на всякий случай написал программку для изменения частоты "IRQ0" в "DOS" - время взбесилось. В "Win95" пока не разобрался как войти в "Ring0", "Ring3" запрещает менять настройки гаваней (портов).
О: Ещё раз - часы идут не от этого таймера.
Я: в первых XT вообще не было автономных часов и пользователь сам вводил начальное время. Потом в "AT" ввели эти часы от батарейки и добавили функции "BIOS" для работы с часами. К слову, чтение занимало довольно внушительное время.
О: я не смог прочитать то, что вы написали. Да и всё равно.
. Посмотрим, что напишут здесь. Если жёсткой ругани не будет, может что и получится. Написать хочется ещё много чего, в том числе и программ.
. Просмотр СОЗУ (регистра) счётчика времямера "Win95" показал, что счёт идёт от 0 до 65.535 (сброс и прерывание по достижению), то есть те же примерно 18,2 Гц. На чтение уходит около 14 мкс - вероятно из-за вызова обработчика прерываний защищённого режима, который разрешает прочитать, но не записать СОЗУ счётчика.
.
. * * *
. Всегда не понимал, почему "Win95" занимает 70 МБ, "Win98" - от 190 МБ и так далее. Для чего нужны такие монстры, и чем они принципиально отличаются от 95? Потихоньку писал своё подобие ОС, но дальше загрузчика не продвинулся (BIOS устанавливает ЕМНИП "CS=0x0000 IP=0x7C00 SS=0x0000 SP=0x0400"). Сейчас думаю, что хорошая ОС начинается с хорошего компилятора, к сборщикам (ассемблерам) и "Си" у меня много претензий. Под "Си++" пишу вообще из-под палки (денежной). В "Си" хочу виды переменных не "char", "short int", "int", ... а "byte", "word", "dword" и другие. Ну и "int" как основной вид закладываемых в стопку (стек) данных.
. Да и англосицизм не жалую. "Реентеррабильная" фунция? А что, повторновходимая не звучит? "Кэш"? Тайник?
. По вид "int" немного ошарашен: в 64 бит системе "gcc" он 32 б ! И соглашение о передаче первых аргументов функции через СОЗУ не признаю. Не то место, где ловить быстродействие.
. "fasm" ещё не видел, собираюсь скачать, посмотреть. "TASM5": не нравится запись шестнадцатеричных чисел типа "0FFFFh", "0xFFFF" красивее, длинные вообще должны разделяться запятой, например "MOV EDX, 0x45EF,3206". Сборщик из "gcc" вообще заумный: " MOVl 8(%EBP), %EAX -> MOV EAX, [EBP+8]".
.
. * * *
. Про выполнители (процессоры). 386 (около 300 транзисторов) - шина адреса 32 или 24 бита, защищённый режим. 486 (около 1 млн транз.) - конвейер целочисленных команд, встроенный математический выполнитель. Из-за конвейера можно говорить о примитивном "CISC-RISC" преобразовании, так как для команд типа "ADD EAX, [EBX]" второй операнд загружается во временное СОЗУ перед исполнением. "Pentium P54" (3,3 млн. транзисторов) - два целочисленных конвейера, один дробночисленный. "Pentium-MMX" (4,5 млн транз.) - дополнительный блок "MMX" целочисленной арифметики в том числе с насыщением (сатурацией). [ 386 около 300 тыс. транз. - опечатка ] "Pentium-2" (7,5 млн транз.) - переделка из "Pentium-Pro" с полным RISC-ядром, переименованием СОЗУ (в книгах пишут, что 16 СОЗУ - 8 целочисленных и 8 дробночисленных отображается на 40 универсальных), внеочередным исполнением и так далее. По "википедии" требовал загрузку микрокода и содержал около 100 ошибок. Часть ошибок обходилась микросборками системной платы, часть - водителями устройств и ОС, оставшаяся часть не проявлялась в большинстве программ. Быстродействие на оптимизированных программах практически не выросло, если не считать быстрого тайника 2 уровня на отдельной высокоскоростной шине. Матем. выполнитель так и остался стопочной архитектуры с ущербным распараллеливанием команд. Пример: "Pentium-2" 450 МГц 490 "MFLOPS", "Sony PlayStation2" (10 мнл. транз.), 300 МГц: 6400 "MFLOPS". Далее вышел "Pentium-3" "SSE" (9 млн транз.) с повышением быстродействия по 32 бит дробным числам на 60% и с новыми ошибками. Про "Pentium 4" вообще лучше промолчать... И верить в легенду, что когда-нибудь выйдет "P55C" по современному "techprocess" с тактовой 1 ГГц, "DDR"-шиной и дробночисленными "SIMD". Для него разработают набор микросборок "440BX2" с поддержкой "ISA"-шины, "Serial ATA", "PCI-express", "USB2.0' и т. д.
. Я использую "Pentium-3" потому, что 233 МГц "Pentium-MMX" на шине 66 МГц не успевает на лету сжимать кино с магнитофона в "704x576" "MJPEG". На "MMX" бывает играю изредка. За 20 лет на нём сгорел линейный стабилизатор напряжения 2,8 В на плате - пришлось поставить в режим 3,3 В и поменять выполнитель на "P54C" 133 МГц.
.
. Вопрос разработчикам
. Считаю, что для ОС нужен "Си"-подобный компилятор. На сборщике (ассемблере) писать большие программы затруднительно. На "Си" программы будут занимать ненамного больше места. Мне на текущий момент больше нравиться пара "Си"-сборщик. По "Си"-подобному компилятору несколько предложений: виды переменных "byte" (8 бит), "word" (16 бит), "dword" (32 бит), "qword" - относительно знаменитого 8086 , "int" - равен размеру слова в стопке. Никаких автооптимизаций - только с приставкой "register" переменные попадают в СОЗУ. Если не попадают - пишем что-то вроде "Warning: variable declared as register placement in RAM". Передача аргументов - только через стопку. Поддержка встраиваемых функций.
. Готов поучаствовать в разработке компилятора. Начать нужно со списка ключевых слов:
void
byte, word, dword, qword
signed, unsigned
float, dfloat
for, while, do, switch, case
break, continue, default
if, else
register, inline
public - вместо static
typedef
volatile
sizeof
assembler
. При компиляции должна создаваться таблица с именами и смещениями переменных и функций. Смещения переменным назначаются в порядке прохода - как в объединении (структуре). Если выравнивание неправильное - пишем предупреждение.
. Компиляция должна переводить "Си"-код в код сборщика. Всё, что в фигурных скобках после слова "assembler" должно проходить в выходной файл без изменений. Символ подчёркивания в имена общих функций и переменных добавлять не нужно.
. Собственно вопрос: использование "Си"-компилятора не противоречит вашей идее?
Vaicheslav97
Posts: 32
Joined: Tue Dec 21, 2021 5:03 pm

Re: Может есть хороший форум на русском?

Post by Vaicheslav97 »

Я не понял часть вопросов и рассуждений, а касательно С с ассемблер подобным отношением к памяти у нас есть С--. Использование С и других похожих языков в место ассемблера в разработке ЯДРА не соответствует проекту. Ведь на Ассемблер завязано множество ключевых особенностей проекта как минимальные расходы максимум эффективности которые на других языках получить ещё сложнее.
User avatar
rgimad
Posts: 162
Joined: Mon Apr 06, 2020 1:09 pm
Has thanked: 6 times
Been thanked: 1 time

Re: Может есть хороший форум на русском?

Post by rgimad »

Vaicheslav97 wrote:Ведь на Ассемблер завязано множество ключевых особенностей проекта как минимальные расходы максимум эффективности которые на других языках получить ещё сложнее.
Неиспользование нормального аллокатора во многих (как правило асмовых) приложениях- максимум эффективности)) ну я про 68.12 в качестве malloc. На каждый чих минимум 4кб дает.
The best way to predict the future is to create it.
Doczom
Posts: 127
Joined: Tue Nov 03, 2020 5:47 pm
Has thanked: 1 time
Been thanked: 2 times

Re: Может есть хороший форум на русском?

Post by Doczom »

rgimad wrote:
Vaicheslav97 wrote:Ведь на Ассемблер завязано множество ключевых особенностей проекта как минимальные расходы максимум эффективности которые на других языках получить ещё сложнее.
Неиспользование нормального аллокатора во многих (как правило асмовых) приложениях- максимум эффективности)) ну я про 68.12 в качестве malloc. На каждый чих минимум 4кб дает.
это ещё не самая большая проблема, некоторые программы даже не используют этот аллокатор, а работают через 64 сисфункцию или вообще память не выделяют динамически, а статически задают область памяти на мегабайт например
user123
Posts: 11
Joined: Wed Jul 13, 2022 10:51 am

Re: Может есть хороший форум на русском?

Post by user123 »

Vaicheslav97 wrote:Я не понял часть вопросов и рассуждений.
. Поясните какие именно, постараюсь подробнее ответить. И если где-то пишу чушь, укажите в чём я неправ. Конструктивной критике буду благодарен.
. Ядра ОС я ещё ни разу не писал, компиляторы тоже. Из того, что писал на "Си", "malloc" ни разу не использовал. Динамическую память запрашивал через "Windows API", в "DOS" выделял статически с запасом, путём написания отдельного узла (модуля) на сборщике (ассемблере). В этом файле писал:

extern _vMain_data0;

sData0 segment para
_vMain_data0 db 65536 dup (?)
ends

Могу немного ошибаться в коде... В "сишном" файле подключал эту область (тоже ЕМНИП):

#include <vctypes.h> - мои виды переменных

unsigned byte *vData = (__seg void *)_vMain_data0+(__near byte *)_vMain_data0;

. На "Microsoft" "Си++" думаю что "new" возвращает указатель на младшие адреса стопковой (стековой) области в надежде, что места хватит.
. Полагаю, что когда поставлю "Колибри" ОС и посмотрю исходные коды ядра, мои представления изменятся. Пока что полагаю, что ядро должно:
* 1 Работать в кольце 0 и запрещать доступ приложениям к гаваням (портам) ввода-вывода.
* 2 Предоставлять функции приложениям такие, что приложениям нет нужды напрямую работать с аппаратной частью. Всё только через функции водителей (драйверов).
* 3 Обрабатывать прерывания, в том числе, когда приложение пытается работать с недопустимыми адресами. То есть в заголовке исполняемого файла должно быть прописано, сколько ему надо под код (Text segment A read/write disable), (Text segment B - а вдруг кто-то захочет самомодифицирующийся код) данные (Data segment A, execution disable), константы (Data segment B, write and execution disable), стопку (Stack segment). Для обмена данными между задачами (процессами) создавать общие области - тут нужно аккуратно, иначе уязвимости.
* 4 По времени забирать управление у потока, который и не думает вызывать "Sleep" или "WaitForSingleObject" или ждать завершения ввода-вывода, работает и работает...
* 5 Настроить отображение видеопамяти (кадрового буфера) на какие-нибудь адреса за пределами установленного ОЗУ, например 0xD000.0000-0.D7FF.FFFF и разрешить приложениям туда обращаться через мьютекс - захватил и рисуй, потом отдай. Если захватил на 1 с и более - завершаем.
* 6 Переключать приложения. Нужно сохранять все СОЗУ (регистры, MMX если есть и тому подобное). Где то в ОЗУ нужно защищённое место под это.
* 7 Работать с файлом подкачки.
* 8 Обнулять выделенную программе ОЗУ. С "DOS" пример не брать не нужно...
* 9 Простенький оконный "manager", опционально, то есть его удаление приведёт к сокращению системных функций. Но без него можно напрямую рисовать.

. Если что, можно тут писать и по-английски, вроде проект интернациональный. Хотя мне читать будет тяжелее, а отвечать могу с ошибками.
. Ещё вопрос: "multiword DMA protocol for ATA" для жёсткого диска под "Intel440BX" поддерживается? Если нет, через "PIO", то ладно, будет куда стремиться, надеюсь описание СОЗУ (регистров) контроллера от "Intel" имеется.
. Ну и ещё вопрос: в "Pentium P54C" да и в 486 тайник (cache L1) может работать в режиме "WriteBack". У него нет "memory range register", как он догадывается не кэшировать запись по адресам видеокарты и других устройств?
. "Си--" тоже посмотрю, первый раз услышал. На следующие 2 недели сильно занят, пропаду ...

. По "gcc" ещё факты. 32 bit:
------------------------------------------------------------------
{
unsigned byte v_a = _fMain_crc8();

v_a += 2;
}
-------------------------------------------------------------------
Warning: truncatination.

v_a += (unsigned byte)2;
v_a(unsigned byte) += 2;
не работает так и не нашёл как 8 бит инкрементировать, приходится писать "v_a = (unsigned byte)(v_a+2)"...

. 64 bit:
------------------------------------------------------------
{
unsigned dword v_a = _fMain_crc32();

v_a += 2;
}
------------------------------------------------------------
молчит... и на это тоже:
------------------------------------------------------------
unsigned dword v_a = 4 , v_b = 5;

v_a = v_a+v_b;
------------------------------------------------------------
Хотя 64-бита результат пишется в 32 бита...
Vaicheslav97
Posts: 32
Joined: Tue Dec 21, 2021 5:03 pm

Re: Может есть хороший форум на русском?

Post by Vaicheslav97 »

могу ответить только по нумеруемым и то не уверен что полностью
1)Разделение на кольца у нас есть но ограничения по портам ввода вывода слабые
2)Ограничения портов ввода вывода у нас такие чтобы в случае если надо приложение могло само могло быть как драйвер в случае если оно работает ну с очень специфичным железом
3)Обработка прерываний есть, когда программы выходит за рамки разрешенной памяти ОС её принудительно закрывает, общие области памяти есть, разделения есть но код не разделяется на модифицируемый или нет.
4)Наша ОС много задачная и поддерживает это распределяя нагрузку между приложениями даже если одно повиснет то это не повесит остальные приложения
5)Я не знаю где находится видеобуфер но поддерживаем стандарты (S)VGA
6)Переключение контекста у нас есть и реализована в рамках многозадачности
7)Файл подкачки отсутствует, по причине что он приводит к общему замедлению системы даже без нагрузки и даёт призрачный шанс пользоваться приложениями на которые не хватает памяти, у нас пока в обозримом будущем нет приложений которым могло бы понадобится 128Мб и выше кроме разве что виртуального диска когда Оперативка выделяется как раздел жесткого диска
8)Не знаю точно но вроде есть.
9)Пока что оконный менеджер вшит в ядро но вроде идут попытки его отделить
User avatar
art_zh
Kernel Developer
Posts: 1462
Joined: Fri Aug 14, 2009 1:46 am

Re: Может есть хороший форум на русском?

Post by art_zh »

rgimad wrote:
Vaicheslav97 wrote:Ведь на Ассемблер завязано множество ключевых особенностей проекта как минимальные расходы максимум эффективности которые на других языках получить ещё сложнее.
Неиспользование нормального аллокатора во многих (как правило асмовых) приложениях- максимум эффективности)) ну я про 68.12 в качестве malloc. На каждый чих минимум 4кб дает.
1) приличные асмовые приложения должны это знать и учитывать.
во избежание неэффективности.

2) в Линуксе kalloc() тоже нарезает драйверам дин.память целыми страницами.
даже если нужно меньше.

3) ядро вообще не обязано заниматься динамической кучей приложений.
в ЯВУ это забота компиляторов.
Евангелие от Иоанна: стих 1

Code: Select all

; В начале было Слово:
B32:        mov     ax, os_stack       ; Selector for os
[/size]
User avatar
Pathoswithin
Mentor/Kernel Developer
Posts: 1298
Joined: Thu Mar 26, 2015 5:16 pm

Re: Может есть хороший форум на русском?

Post by Pathoswithin »

Проще сказать, что на системном уровне память всегда выделяется страницами по 4 кб, и все ОС её так выдают. Более мелкая нарезка происходит на пользовательском уровне; а в библиотеке или в самом приложении — это уже не принципиально. Может даже лучше чтоб программист понимал, что при не правильном обращении к памяти в пределах 4 кб системной ошибки не будет.
user123
Posts: 11
Joined: Wed Jul 13, 2022 10:51 am

Re: Может есть хороший форум на русском?

Post by user123 »

. Выдалось немного времени с утра...
art_zh wrote: Tue Jul 19, 2022 4:50 pm 3) ядро вообще не обязано заниматься динамической кучей приложений.
в ЯВУ это забота компиляторов.
. Вот это немного недопонял. А если размер динамически создаваемых областей на этапе компиляции неизвестен. Например, пользователь работает с расширяющийся таблицей, добавляя строки. Я бы наращивал выделенное ОЗУ блоками по 128 кБ.
. И ещё не понимаю, что такое "C++ runtime modules", без которых не работают некоторые программы. Предполагаю, что это превращает компилируемый язык в интерпретируемый.
. Добавление 6 сент. 2022. Прочитал раздел на этом ресурсе с анекдотами...
. 1960-е. Мужик купил в городе проводное радио 36 В. Привёз домой в деревню, говорит жене:
. - Это устройство для приёма звука из удалённых студий, где собираются известные люди.
. - По-моему тебя обманули. Какая-то неказистая продырявленная коробка.
. - Вот сейчас включим и проверим. (Подносит вилку к розетке 220 В...)
. - Не надо, слышь, электричество испортишь.
. Мужик всё равно включает - раздался гул с треском.
. - Выключи эту дрянь! Говорю, обманули дурака! Вези назад и разбей продавцу об рожу.
. Тут гул стал тише - у динамика оторвался диффузор от катушки и пошёл дым - регулировочный резистор перегрелся. Мужик:
. - Неужели не понятно - настраивают, курят - скоро передача начнётся!
.
. Добавление 26 сент., 2022 . Грамоту от "Intel 386" на одном ресурсе переписали "как есть". Видимо умный программист не должен обращать на такое внимание. "Paging enabled" и "disabled" имеется ввиду с "#". И только меня жёстко отчитывают за подобное.
Attachments
UserLoh.png
UserLoh.png (27.96 KiB) Viewed 50 times
Last edited by user123 on Mon Sep 26, 2022 9:32 am, edited 6 times in total.
user123
Posts: 11
Joined: Wed Jul 13, 2022 10:51 am

Re: Может есть хороший форум на русском?

Post by user123 »

Code: Select all



                    -------------------------------
                    Компилятор сборщика (assembler)
                    -------------------------------


                    Введение

    Просьба сильно не ругаться, я сам читаю это как руководящую грамоту
(document) для написания компилятора. На "commercial" успех даже не рассчитываю,
так как сейчас ценится умение осваивать средства. Народное большинство неявно
одобряет, считая что для просмотра паутины (web) нужно минимум 4 ГиБ ОЗУ и
примерно такого же размера ОС, способная работать только на мультиядерном
"central processor". Даже если показать, что это не нужно, скорее всего будет
реакция "всё равно у тебя что-то не так и рано-поздно вылезет, даже связываться
не хочу с твоими детскими игрушками. Что, хочешь сказать все вокруг такие
идиоты, один ты умный?" Всем всё равно сколько транзисторов в выполнителе,
сколько ошибок и уязвимостей, какие правила навязывает производитель, "AGTL,
AGTL+, Plug&Pray-Play, PCI2.0/PCI2.1/... , SSE/SSE2/SSE3..., AVX/AVX2 , nVidia
Detonator/CUDA, DDR2/DDR3 , QDR, CPU stepping" это же круто! Если нужны
деньги - приложения для крутых ОС на крутых языках, и плевать на
программистские "visual studio monsters" тоже гигабайтных размеров, так как
главное - скорость разработки и переносимость. Более того, весьма вероятно, что
кто-то из крутых денежных воротил заберёт идеи отсюда и наварится ещё на пару
яхт с самолётами.
    Во избежании путаницы некоторые понятия:

            область (segment) - участок ОЗУ с расположенными командами
                                и-или данными
 ближний адрес (near address) - 16 или 32 бит число, обозначающее смещение от
                                начала области до предмета
  дальний адрес (far address) - 32 или 48 бит число, обозначающее не только
                                смещение, но и адрес самой области
областной адрес (segm. addr.) - старшие 16 бит дальнего адреса, показывающие
                                адрес области

    Начну с описания того, как я хотел бы видеть исходный код.
    Ключевые слова адресов на переменные:

byte, word, dword, qword, float, dfloat

    Уточнители:

near, far, public, extern

    Ключевые слова разбивки на узлы:

module, segment, endSegment

    Ключевые слова использования наборов команд:

use8086, use386_Real, use386_Protect

    Ключевое слово определения выражений на этапе предкомпиляции:

#define

    Операторы и очерёдность с направлением прохода ("Л" - слева направо, "П" -
справа налево):
--------------------------------------------------------------------------------
           Описание
--------------------------------------------------------------------------------
 1П   &    Однооперандный, вставка ближнего адреса. К дальнему адресу тоже
           применим, так как из дальнего всегда можно выделить ближний.
      -    Однооперандный, изменение знака
 2Л   *    Двухоперандный, умножение.
      /    Двухоперандный, деление.
 3Л   +    Двухоперандный, сложение.
      -    Двухоперандный, вычитание.
 4Л   <<   Двухоперадный, побитовый сдвиг влево.
      >>   Двухоперадный, побитовый сдвиг вправо с учётом знака.
--------------------------------------------------------------------------------

Операторы применяются только на этапе предкомпиляции. Вычисления производить с
размерностью 32 бита для целых чисел и 64 бита для дробных. Поэтому у
компилятора должен быть ключ запуска "-8086", говорящий о составный 32 или 64
битных вычислениях в 16 битных СОЗУ (registers). Числа записываются по
английским правилам: "," - разделение цифр, "." - разделение целой и
дробной части.
    Ключевые символы указания области видимости местных меток, области узла:

{   }


                    Создание "DOS COM-file"

    Одна из самых простых программ, состоящей из одной области (segment).
Загрузчик должен выделить 64 киБ ОЗУ, установить "DS, SS" на областную часть
адреса выделенного ОЗУ, "SP" на 0xFFFE, саму ячейку SS:0xFFFE на ближний адрес
какой-то функции (SP предуменьшается на 2 при записи в стопку) и передать
управление по адресу "(старшая часть адреса выделенного ОЗУ):0x0100".
    Файл "Main.asm":
--------------------------------------------------------------------------------
use8086 ; почти как в паскале, использовать сборщик кодов операций под 8086

extern near _fMain_fillMemoryB: ; внешняя ближняя метка, "near" можно опустить,
                                ; но в отладочных целях привожу

; Единственная область (segment) "COM"-файла "DOS". Ближняя часть всех
; адресов в ней - смещения относительно начала этой области. Области всегда
; общие и не нуждаются в уточнителе "public". Для хранения областной части
; адресов областей, связыватель создаёт общие переменные в узле
; неинициализируемых данных. Имя переменных - приставка "_vSegmAddr" с именем
; указываемой области, например, "_vSegmAddr_sCom".
segment _sCom

public module _mCom_header
{
  ; Этот узел заполняется связывателем (linker) для построения заголовка
  ; "DOS COM file" размером 256 байт. При связывании ко всем адресам и меткам,
  ; которые идут позже, прибавить размер этого узла.
}

public module _mCom_code
{
  ; Этот узел состоит из машинных команд. Вообще метка старта необязательна,
  ; но для солидности главная функция программы должна быть объявлена.

  ; public unsigned word _fOs_main(void); // главная функция, вызываемая ОС
  ;
public _fOs_main: ; ближняя метка, при компиляции равна 0x0000 , при связывании
                  ; прибавить размер "_mCom_header"

  MOV  [_vSegmAddr_sCom], CS ; может где-то в заголовке загруженного в ОЗУ
                             ; файла загрузчик разместит областную часть
                             ; адреса, пока не знаю, поэтому пока
                             ; пишем так - сохранить в ОЗУ

  MOV  AH, 0x09
  MOV  DX, &vMess ; ближний адрес "vMess", эта команда не обращается к ОЗУ, так
                    как адрес вычисляется на этапе связывания
  INT  0x21

  MOV  AX, 256
  PUSH AX
  MOV  AL, 255
  PUSH AX
  MOV  AX, [_vSegmAddr_sCom] ; эта команда обращается к ОЗУ
  PUSH AX
  MOV  AX, &vData
  PUSH AX
  CALL _fMain_fillMemoryB ; так как ближняя функция, то собирать "CALL near"
  ADD  SP, 8

  MOV  AX, 0x4C00
  INT  0x21

  ; Этот узел общий как и предыдущий. То есть его размер будет известен только
  ; при связывании.
}

public module _mCom_dataInit
{
  ; Узел инициализируемых данных. Данные отсюда как и из предыдущих узлов
  ; попадут в связываемый файл. При запуске загрузчик скопирует файл в ОЗУ,
  ; немного изменит заголовок, а этот узел останется нетронутым и переменные
  ; получат нужные значения.

  byte vMess[] "Hello, world!\0" ; адрес данных, при компиляции 0x0000 , при
                                 ; связывании прибавить размер
                                 ; "_mHeader+_mCode", уточнитель "near" опущен
}

public module word _mCom_dataNoInit ; этот узел разместить по чётному адресу,
                                    ; добавив впереди пустой байт
                                    ; при необходимости
{
  ; Этот узел не должен быть в связываемом файле. Но все адреса должны
  ; быть вычислены и указывать на выделенную программе ОЗУ. Связыватель должен
  ; вычислить размер этого общего узла, хотя для "COM" это и необязательно -
  ; всё равно программе выделится 65 кБ. Для выравнивания по чётному адресу
  ; к начальному адресу при необходимости связыватель прибавляет единицу.

  public word _vMain_sTinyAddr ; эта переменная попадает на чётный адрес и
                               ; выбирается в 8086 быстрее
  byte vData[256]
}

endSegment
--------------------------------------------------------------------------------

    Файл "Funct0.asm":
--------------------------------------------------------------------------------
use8086

; Продолжение общего узла. Так как область не указана, то связыватель ищет
; такой узел во всех областях. При связывании предметный (object) код из этого
; файла нужно подключать вторым, иначе будет начало общего узла.
public module _mCom_code
{
  ; public void _fMain_fillMemoryB(unsigned byte __far *v_destin,
  ;   unsigned byte v_value, unsigned int v_quant);

public near _fMain_fillMemoryB:
  ; Соглашение: "SI, DI, BP, DS" не портить, остальные можно. Если вышестоящая
  ; функция использует "AX" и другие для своих нужд, то сохраняет их перед
  ; вызовом нижестоящей.

  PUSH BP
  MOV  BP, SP
  PUSH DI

  LES  DI, [BP+4]
  MOV  AL, [BP+8]
  MOV  CX, [BP+10]
  CLD
  REP
  STOSB

  POP  DI
  POP  BP
  RET ; по умолчанию полагаем ближний
}
--------------------------------------------------------------------------------


                    Создание "DOS EXE-file"

    Файл "EXE" может содержать несколько областей кода и данных. А так же
стопку в отдельной области. Загрузчик должен выделить ОЗУ под каждую область,
желательно по соседним адресам, загрузить соответствующие части из файла,
настроить "DS" на главную область данных, "SS:SP" - на область стопки, и
передать управление на главную область кода.
    Файл "Main.asm":
--------------------------------------------------------------------------------
use8086

extern far _fMain_funct:
extern far _vMain_data

segment _sExeCodeMain ; главная область кода, исполняющаяся первой, сюда
                      ; указывает "CS:IP" по настройке загрузчика, IP часто
                      ; равен 0x0000

public module _mExe_code
{
  ; unsigned word _fOs_main(void);
_fOs_main:
  SEG   CS
  CALL  [_fMain_funct] ; дальний вызов, так как старшая часть адреса
                       ; становится известной только после загрузки, она
                       ; выбирается из ОЗУ по отведённому адресу

  MOV   DI, &_vMain_data
  SEG   CS
  MOV   DS, [_s]

  MOV   AX, 0x4C00
  INT   0x21
}

public module _mExe_dataNoInit
{
  ; Здесь связывать должен разместить адреса дальних вызовов, старшая часть
  ; которых инициализируются загрузчиком. А также старшие части дальних
  ; адресов данных. Здесь создастся переменная "dword _fMain_funct 0", в
  ; которую связыватель подставит ближний адрес функции, а загрузочный код -
  ; дальний.
}

endSegment

segment _sExeDataMain ; главная область данных, сюда указывает "DS" по
                      ; настройке загрузчика
  ; В "DOS" это вроде "PSP", но тут я плаваю.
endSegment
--------------------------------------------------------------------------------

    Файл "Funct0.asm":
--------------------------------------------------------------------------------
segment _sExeCodeExt

public module _mExe_code
{

public far _fMain_funct:
  PUSH BP
  MOV  BP, SP

  {
    ; int v_i;
    ;
    ; for(v_i = 5; v_i > 0; v_i--)

    PUSH AX

    MOV  [BP-2], 5
  l_loopCheck: ; эта и последующие метки, начинающиеся на "l_", видны только в
               ; пределах фигурных скобок
    CMP  [BP-2], 0
    JB   l_loopExit
  l_loop:
    ;

    DEC  [BP-2]
    JMP  l_loopCheck
  l_loopExit:
  }

  POP  BP
  RET  far
}

endSegment

segment _sExeDataNoInit

public module _mExe_data
{
  public word far _vMain_data;
}

end segment
--------------------------------------------------------------------------------

    И теперь вопрос - как вычислить старшую часть дальних адресов? Очевидно,
что она будет известна только после загрузки областей в ОЗУ. Ключ к ответу
поищем в команде "CALL far":

CALL far 0xXXXX , 0xXXXX ; прямой вызов, код 0x9A
CALL far [reg/imm] ; косвенный вызов по прямому или косвенному адресу, код 0xFF

Понятно, что команда 0x09 подойдёт не очень хорошо: загрузчику или самой
программе придётся корректировать старшие части дальних адресов в каждой
команде. А это уже самомодифицирующийся код. Более оптимальное решение -
создать в ОЗУ таблицу дальних адресов, куда загрузчик поместит адреса и
использовать команду 0xFF . Чтобы было меньше манипуляций, таблицу размещаем в
главной области кода.


                    Основы анализа входного файла

    Файл обрабатывать построчно, то есть создать хранилище (buffer) под строку и
помещать в неё байты из файла пока не встретится пара (0x0D 0x0A). Строку
разбить на разделённые пробелами слова, комментарии. Из слов пытаться
анализировать фразу.
    Рассмотрим анализ файла "Main.asm" для "DOS COM file":

* Строка 1: "use8086" - одно ключевое слово.
* Строка 2: нет слов.
* Строка 3: "extern", "near", "_fMain_fillMemoryB:", ";" далее неважно. Два
  первых слова - ключевые, третье - незнакомое.
* ...

    Нужно заготовить допустимые фразы:

use8086
extern <unknow>:
extern near <unknow>:
extern far <unknow>:
extern byte <unknow>
extern word <unknow>
...

Так перечислять довольно утомительно. Лучше разбить слова на объединения и
оперировать названиями объединений.
. Пока сырой вариант, оформлен плохо, буду дорабатывать. Грамоты пишу в "DOS"-редакторе, "Word" и другие "monsters" под тяжёлую графику с периодическими подвисаниями не использую. Хотел разместить в удобночитаемом виде с моноширинным шрифтом - не получилось.

Code: Select all

* Объединение "А": "byte", "word", "dword", "qword", "float", "dfloat".
* Объединение "А1": "[X]", где "X" - кол-во элементов, "[]".
* Объединение "А2": "X, X, X, ...", где "X" - произвольные числа в произвольном
  количестве, строка в кавычках.
* Объединение "Б": "near, far".
* Объединение "В": "module, segment, endSegment".
* Объединение "Г": "use8086, use386_Real, use386_Protect".
* Объединение "Д": "public".
* Объединение "Е": "MOV", "INT", "ADD", "PUSH", "POP", "REP", ...
* Объединение "Ж": всё остальное.

    Допустимые фразы (точка означает, что на этом узле фраза может быть
закончена, цифра после точки - ссылка на описание значения фразы).

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

            Д
            |
    -----------------
    |       |       |
    А      Ж.2      Б
    |               |
   Ж.1          ---------
                |       |
                А      Ж.4
                |
               Ж.3    
    
-------------------------------------------------
 1   Определение ближней переменной.
 2   Определение ближней метки.
 3   Определение ближней или дальней переменной.
 4   Определение ближней или дальней метки.
-------------------------------------------------

    Создание предметов
    ------------------
    При создании инициализированного множества с указанием количества элементов
проверять соответствие. Создание неинициализированного множества без указания
количества элементов - ошибка. Создание допускается только внутри узла.
    Создание ближних предметов:

          А
          |
         Ж.1
          |
      ---------
      |       |
    А1.2    А2.4
      |
    А2.3

-----------------------------------------------
 1   Создание неинициализированной переменной.
 2   Создание неинициализированного множества.
 3   Создание инициализированной множества.
 4   Создание инициализированной переменной.
-----------------------------------------------

    Создание ближних или дальних предметов:

          Б
          |
     далее как в
  предыдущей схеме
. Компилятор пишется потихоньку. Не могу найти информацию по "OMF"-предметным файлам, тьфу, "COFF". И "OMF-32". Кто знает, подскажите? Впрочем наверное не нужно, так как судя по всему меня и здесь записали в слабоумные. И выхода нет. Приведу пример:
- Товар на 10% подорожал, потом на 10% подешевел. Как изменилась его цена по сравнению с первоначальной?
- А подешевел относительно новой (подорожавшей) цены или старой?
- Всё с вашим интеллектом понятно. Тест окончен.
- Но почему? Я же по существу спрашиваю?
- Потому что надо быть всесторонне развитым человеком и не задавать идиотских вопросов. Всего словами не выскажешь. Кое-где и мозг включать надо. Если он есть.
Last edited by user123 on Thu Sep 08, 2022 7:43 am, edited 4 times in total.
Valery
Posts: 81
Joined: Tue Jul 19, 2022 11:41 am
Has thanked: 1 time
Been thanked: 6 times

Re: Может есть хороший форум на русском?

Post by Valery »

5)Я не знаю где находится видеобуфер но поддерживаем стандарты (S)VGA
В документации ( http://wiki.kolibrios.org/wiki/SysFn61/ru ) написано:
Программе доступны данные графического экрана (область памяти, которая собственно и отображает содержимое экрана) напрямую без вызовов системных функций через селектор gs:

Code: Select all

mov eax, [gs:0] 
В файле исходников ядра core/mtrr.inc написано (строка 898):

Code: Select all

; LFB is mapped to virtual address LFB_BASE,
В файле const.inc определено (строка 279):

Code: Select all

LFB_BASE            = 0xFE000000
Насколько понимаю , физический адрес получается от BIOS (с некоторой настройкой)
, возможно его изменяет специализированный драйвер видео карты (таковые имеются ...)
а затем отображается на виртуальный LFB_BASE = 0xFE000000 , который доступен для записи в том числе и
в ring3 - пользовательском режиме (лично мне такая беспечность непонятна : нормальный пользователь при "невменяемом" экране решить проблему может только кнопкой RESET)

Номера строк, естественно, примерные, ибо файл может быть изменён в процессе разработки

P.S.
Вы собираетесь разрабатывать что-то новое для 8086, 80386 real mode. 80386 protected mode .
А вас в стране наверное налажено производство аналогов этих процессоров по цене чуть большей avr для Arduino ...
А вот с процессорами amd64 напряжёнка ... Тогда всё встаёт на свои места ...

В моей стране : avr - нет проблем. arm - тоже нет проблем, amd64 - тем более нет проблем, mips вроде как можно найти под вывеской avr32, но на чипсете с возможностями Arduino (а хотелось бы - с чипсетом Raspberri Pi). Насчёт ia32 без amd64, как раз наблюдая
за Kolibri OS , понял, что вроде как в Китае можно заказать (но по цене, за которую я могу подержанный системный блок amd64 приобрести).
Боюсь, что следующий логичный шаг после введения UEFI будет новая линейка процессоров, у которых ничего, кроме amd64 long mode , просто нет - на таких компьютерах Kolibri OS уже не запустишь в принципе (даже если оставят amd64 compatability mode)
user123
Posts: 11
Joined: Wed Jul 13, 2022 10:51 am

Re: Может есть хороший форум на русском?

Post by user123 »

. Я сохранил себе 286 , "Pentium/2/3". От 286 и "Pentium" я просто в восторге. "DOS/Windows 95" просто летают, писать программы одно удовольствие. На "ATmega328/ATtiny4313" пишу ради денег в громоздкой "AVR Studio" под "Windows XP/7/10". "С++" туда же. Компилятор попытаюсь начать на своём оборудовании и под него.
. Решил вспомнить как это было и написать настоящий "DOS COM" в "Borland TASM5". И посмотреть в отладчике. Код рабочий.

Code: Select all

MAIN.ASM
--------------------------------------------------------------------------------
.8086

extrn _fMain_fillMemoryB:near

; На самом деле программа состоит из одной области 64 киБ, но по законам
; "Borland" создаём бутафорские области (узлы). В этом узле собирается код
; из всех файлов:
_sCode segment para public
; * * *
  assume CS:_sCode, DS:_sCode ; привязка этого узла, иначе компилятор
                              ; откажется обрабатывать команды перехода и при
                              ; обращениях к данным начнёт подписывать
                              ; приставку "SEG CS"

  ; Подписка приставки - самодеятельность. В руководстве к "processor" написано
  ; "при обращении к ОЗУ без указания областного СОЗУ через "[BX], [SI], [DI]"
  ; считать что областной адрес в "DS", через "[BP], [SP]" - в "SS". Если что,
  ; программист сам в состоянии подписать приставку замены умалчиваемого СОЗУ.

  vComHeader db 256 dup (?) ; заголовок "DOS COM PSP", в исполняемом файле
                            ; отсутствует вообще, то есть строится загрузчиком
  ;
fMain: ; эта метка получает адрес 256, исполняемый файл начинается отсюда
  ;
  MOV  [_sCode:_vSegmAddr_sCode], CS ; адрес "_vSegmAddr_sCode" относительно
                                     ; узла "_sCode"

  ; Вообще-то похоже, что подставляется значение "vSegmAddr_sCode", вроде как
  ; нужно по понятиям "Borland" слово "offset" - но так работает а иначе - нет.
  ; И если написать "MOV  AX, _vSegmAddr_sCode", то в "AX" попадёт не адрес...

  MOV  AH, 009h
  MOV  DX, offset _sCode:vMess ; здесь видна другая проблема: хотя в узле данных
                               ; сказано, что "CS, DS" привязаны к "_sCode",
                               ; всё равно нужно указывать как считать
                               ; ближний адрес "vMess"

  ; Иначе берётся адрес относительно начала "_sDataInit".

  INT  021h

  MOV  AX, 256
  PUSH AX
  MOV  AL, 255
  PUSH AX
  MOV  AX, [_sCode:_vSegmAddr_sCode] ; снова умный компилятор подставляет адрес
                                     ; переменной "_vSegmAdd_sCode" и запрещает
                                     ; писать "offset"
  PUSH AX
  MOV  AX, offset _sCode:vData
  PUSH AX
  CALL _fMain_fillMemoryB
  ADD  SP, 8

  MOV  AX, 04C00h
  INT  021h

  ; Сюда может быть добавлен код (и будет добавлен) и даже инициализируемые
  ; данные (только смысл?) из других файлов. Адреса переменных ниже
  ; переносятся связывателем.
ends

; Это все та же единственная область. Чтобы инициализируемые данные пошли после
; всех команд объявляется эта бутафорская облась - узел:
_sDataInit segment word public
; * * *
  assume CS:_sCode, DS:_sCode ; не понимаю

  vMess db "Hello, word!$"

  ; На этом узле исполняемый файл кончается.
ends

; И это та же единственная область. Узел, которая идёт позже всех и в файл не
; попадает. Адреса вычисляются.
_sDataNoInit segment word public
  _vSegmAddr_sCode dw ? ; эта переменная попадает на чётный адрес

  vData db 256 dup (?)
ends

end fMain
--------------------------------------------------------------------------------

FUNCT00.ASM
--------------------------------------------------------------------------------
.8086

public _fMain_fillMemoryB

_sCode segment byte public
  ; Здесь нет команд перехода по вычисляемым адресам, про "assume"
  ; можно забыть!

  ; public void _fMain_fillMemoryB(unsigned byte __far *v_data,
  ;   unsigned byte v_value, unsigned int v_quant);
_fMain_fillMemoryB: ; я бы хотел public написать здесь, но компилятор
                    ; не понимает
  PUSH  BP
  MOV   BP, SP
  PUSH  DI
  PUSH  DS

  CLD
  LDS   DI, [BP+4]
  MOV   AL, [BP+8]
  MOV   CX, [BP+10]

  REP
  STOSB

  POP   DS
  POP   DI
  POP   BP
  RET ; по умолчанию полагаем ближний
ends

end
--------------------------------------------------------------------------------

; Итого получилась программа размером 71 Б.
. Видно, что свой компилятор не помешает.
KPG
Posts: 46
Joined: Tue Dec 08, 2020 10:26 pm

Re: Может есть хороший форум на русском?

Post by KPG »

user123 wrote: Sun Jul 31, 2022 11:51 am На "ATmega328/ATtiny4313" пишу ради денег в громоздкой "AVR Studio" под "Windows XP/7/10". "С++" туда же. Компилятор попытаюсь начать на своём оборудовании и под него.
Не думали рассмотреть разработку ПО для МК (разных и AVR) на Форт (Forth) языке?
Для AVR, к примеру,
1. amForth
2. Форт-ассемблер для AVR
3. AVRForth
4. FlashForth
...
P.S. Для других/разных МК/ тоже достаточно сделано инструментария для разработки ПО в рамках Форт системы. :)

Форт также легко расширить до понимания других языков
uBasic for 4th
CC64 is a small-C compiler, written in Forth (here's why), targeting the 6502 CPU.
...
Разместить FORTH в 512 байтах
user123
Posts: 11
Joined: Wed Jul 13, 2022 10:51 am

Re: Может есть хороший форум на русском?

Post by user123 »

. Изучаю, разбираюсь, материал про язык-4 незнакомый, даже не знаю полезно ли... оценить пока не могу. Хочу писать "assembler" на "TASM5". Думаю самое нужное введение - ключевые символы "{", "}" для местных меток или адресов.
. Проблема по ссылкам интересная: что минимально нужно для полноценного независимого программирования. Мне кажется 16-ричный редактор с возможностью чтения-записи через "BIOS INT 0x13".
KPG
Posts: 46
Joined: Tue Dec 08, 2020 10:26 pm

Re: Может есть хороший форум на русском?

Post by KPG »

user123 wrote: Tue Aug 02, 2022 12:21 pm . Изучаю, разбираюсь, материал про язык-4 незнакомый, даже не знаю полезно ли... оценить пока не могу.
Начать можно с прочтения таких книг.
С.Н.БАРАНОВ Н.Р. НОЗДРУНОВ ЯЗЫК ФОРТ И ЕГО РЕАЛИЗАЦИИ
Л.Броуди "Начальный курс программирования на языке Форт"
ЛЕО БРОУДИ СПОСОБ МЫШЛЕНИЯ - ФОРТ ЯЗЫК И ФИЛОСОФИЯ ДЛЯ РЕШЕНИЯ ЗАДАЧ
...
FORTH (Computer+program+language)

Сейчас популярен в реализации база стандарта Forth-94.


P.S. http://fforum.winglion.ru/ рускоязычная площадка пользователей Форт языка.

На Github много проектов отображается при вводе слова Forth в поисковом запросе.
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest