KIV Я свой ассемблер хотел делать по нескольким причинам: 1. Проявить себя в логической задачи; 2. Лучше познакомиться с процессором (да и команды сделать только те, которые мне нужны); 3. Чтобы мой ассемблер я мог использовать для написания программ из моей ОС. Вот если я буду использовать FASM, напишу на нём ОС. Мне же всё равно нужно будет делать компилятор, чтобы я мог в ней писать для себя программы. Так ведь? Не буду же я писать автору (авторам) FASM и просить чтобы они разработали его для моей ОС. Вы ведь пока пишите программы для своей ОС из под другой ОС, на которой работает FASM. Так ведь?
У fasm исходники открыты (не GPL, но модифицировать можно). Он специально построен так, чтобы его легко можно было перенести в другую ОС. Кстати, так поступили в KolibriOS. Чтобы он у вас заработал достаточно реализовать 32-битные сегменты, потому что fasm 32 битный. Как портировать fasm? посмотрите system.inc и fasm.asm в папке source/win32, source/dos, source/libc или source/linux
KIV То есть в длинном режиме нужно будет всё равно возвращаться в совместимый режим? Это не есть хорошо для меня. Эх, видимо придётся реализовать свой ассемблер. У меня больше на данный момент вызывает трудность не с проходами, адресами и запоминанием переменных и прочего (я по этой части справлюсь, люблю думать и решать разные задачи), а проблема у меня именно с машинными инструкциями. Я не видел нормального описания. Так, только отдельными статьями видел где показано как составляются команду пересылки данных (mov). Кстати, я думал что сегментный регистр кода (CS), автоматически устанавливается в 0x07C0 при передаче управления на загрузчик. А оказывается что там 0x0000. А команда: Code (Text): code16: mov CS,code16 И: Code (Text): code16: mov AX,code16 mov CS,AX Вызывают ошибку. Так как же мне CS направить на начало кода?
KIV Сразу две ошибки Во-первых, чтобы ОС была легко переносима на разные архитектуры, она должна быть соответствующим образом спроектирована -- именно это является главным требованием. В частности, она не должна слишком сильно зависеть от методы обработки прерываний, организации ввода-вывода и т.п. конкретной аппаратной платформы. Следствием же этого является неэффективность подобной системы на практически любой платформе (UNIX -- крайне неэффективная система на самом деле, почему долгое время и не находила практического применения: уж очень много она сжирала памяти, работая при этом слишком медленно по сравнению со специализированными ОС). Ну а во-вторых, писать переносимую ОС можно на любом компилируемом языке, а далеко не только на Си. Кстати говоря, куда лучше переносимость будет, если писать на Аде -- вследствие крайне жёсткой стандартизации этого языка, а также наличия стандартных средств для описания всяких низкоуровневых вещей (типа привязки переменных к адресам памяти, расписывания записей по битам и т.п.). Что Си -- самый популярный язык системного программирования, это бесспорно, но на этом его достоинства заканчиваются... (ну, можно ещё считать достоинством, что в нём надо нажимать куда меньше клавиш при наборе исходников, но для меня это скорей недостаток, ведь на выходе получается неудобочитаемый и потенциально ненадёжный код; впрочем, обсуждение этих вопросов обычно приводит к холивару -- сами знаете).
s3dworld Ага, фантастику, причём антинаучную Многоядерность -- это самая что ни на есть обычная многопроцессорность, т.е. наличие в компутере нескольких равноправных процессоров (SMP -- симметричное мультипроцессирование; бывает, но не на ПК, ещё AMP -- ассиметричное, где процессоры выполняют разные функции). Ничего принципиально нового в этом нет, подобные машины точно были уже в начале 1960-х, а возможно, и раньше; единственное, что с тех пор действительно заметно изменилось, -- это размеры: раньше один процессор занимал пару шкафов, сейчас несколько процессоров находятся на одном кристалле кремния Каждый процессор многопроцессорной системы (а таковые даже среди ПК существовали и до появления многоядерных кристаллов; например, мой предыдущий комп имел два Xeon'а, т.е. был двухпроцессорным; кроме того, каждый из них поддерживал технологию Hyper Threading, т.е. с точки зрения программиста (и оси) выглядел как два независимых процессора, почему в моей машине логически было четыре процессора) выполняет свою собственную программу (конечно, может получиться так, что они одновременно выполняют одну и ту же, но это лишь частный случай). Никаких прямых средств программирования многопроцессорной обработки ассемблер не предусматривает; взаимодействие процессоров между собой в ИА-32 реализовано внешним по отношению к ним образом -- через APIC (усовершенствованный контроллер прерываний). В общем, геморрой ещё тот, что для Интел вполне традиционно: им религия не позволяет создавать нормальные процессорные архитектуры, не содержащие кучу костылей и извратов. Поскольку Вы и с обычным-то программированием (для однопроцессорных систем) знакомы пока что слабенько, не заморачивайтесь этим, а изучайте обычное, самое что ни на есть традиционное программирование, а многопроцессорные системы подождут.
SII Да, вполне верное направление для дальнейшей работы. Как Вы считаете, стоит ли мне свой мини-ассемблер начать делать для того чтобы лучше познакомиться с процессором?
SII Да и всё-таки интересно: это же получается что у каждого ядра свои регистры (причём скорее всего все регистры свои, хотя не исключаю что есть какой-то общий, для синхронизации работы). Да и всё равно же ведь как-то можно управлять работой каждого ядра. Ведь та же операционная система Microsoft Windows XP позволяет переключить задачу на определённое ядро (то есть сами решаем какое ядро что будет делать).
s3dworld Сколько-нибудь полноценный ассемблер -- весьма сложная программа. Я вот сейчас свой клепаю (правда, под АРМ, но в перспективе и для ИА-32) -- уже около 10 тыс. строк на Паскале (Дельфях, если точней), а пока он ещё ничего не транслирует, я лишь ещё только подбираюсь к директивам определения данных (.WORD и т.п.), а за инструкции процессора ещё и не думал браться. Конечно, изрядную часть составляют комментарии, пустые (для читабельности) строки и т.п., но всё же объём довольно приличный. Так что хорошенько подумайте, надо ли Вам оно...
Вся синхронизация -- через APIC, отчасти через ACPI (переход в сон и выход из сна, ну и тому подобные вещи), через память (ОЗУ-то общее, как и внешние устройства, и БИОС, и прочая). А регистры, есно, у каждого процессора полностью свои. Каждое ядро -- это просто совершенно отдельный процессор (или даже два процессора с логической точки зрения, если включена поддержка Hyper Threading), и работает он независимо от остальных.
SII У меня трёх-ядерный процессор. Получается что я могу одно ядро оставить в реальном режиме (R-Mode), другое ядро оставить в защищённом режиме (P-Mode) и последнее ядро - в длинном режиме (L-Mode). Если процессору в длинном режиме нужны данные из прерывания и функции BIOS, то процессор, который находится в R-Mode, это делает и результат выкладывает в память где-нибудь в первом мегабайте данных (может быть возможно как-то между процессорами обмениваться данными, либо что-то промежуточное между процессорами, но не ОЗУ). После этого процессор в L-Mode обращается к этому первому мегабайту в памяти и получает значение. Это так возможно на практике или это снова мои фантазии?
s3dworld Да, разные процессоры (ядра) могут находиться в разных режимах, и между ними можно обмениваться информацией, пользуясь общим полем памяти, так что это не фантазия. Вот только особого смысла в этом лично я не вижу: проще переключаться по мере надобности между режимами на одном процессоре, а остальные не трогать вообще (чтобы их корректно запустить, тоже повозиться придётся).
SII Вот уже хочется руки в это кинуть...но чувствую что равно. А как мне быть с этим: Я думал что сегментный регистр кода (CS), автоматически устанавливается в 0x07C0 при передаче управления на загрузчик. А оказывается что там 0x0000. А команда: Code (Text): code16: mov CS,code16 И: Code (Text): code16: mov AX,code16 mov CS,AX Вызывают ошибку. Так как же мне CS направить на начало кода?
s3dworld Запись в CS выполняют команды дальнего перехода (JMP FAR и CALL FAR), ведь изменение CS автоматически означает переход (потому-то MOV и не позволяет его изменить -- следующая команда будет находиться тогда фиг знает где). Но зачем Вам это делать? Когда БИОС передаёт управление загрузчику, она выполняет переход на адрес 0000:7C00. Зачем Вам непременно нужно менять сегмент?
SII Я думал поставить в CS значение 0x07C0 и обращаться так: Code (Text): mov AL,byte [CS:0] mov BL,byte [CS:1] mov CL,byte [CS:2] mov DL,byte [CS:3] В общем по-байтово считывать сами инструкции. Так можно? Или это делается через другой сегментный регистр (скажем ES): Code (Text): code16: ... ; Какой-то код ... mov AX,code16 mov ES,AX mov BX,0 mov AL,byte [ES:BX] Как делается?
Можно и так, и эдак. Но просто так изменить CS нельзя, поскольку это вызывает переход; всегда надо менять CS вместе с (E)IP. А что мешает считывать коды команд, начиная со смещения 7C00, а не с нуля?
SII Да собственно ничего. Просто хотел как бы представит так, что начало моей программы как начало массива. И просто указывать нужный тебе элемент по индексу. Я вот заметил что не все регистры общего назначения можно использовать для адресации. Так ли это, ли это одно из двух: 1. Ошибка в FASM; 2. Я что-то не так понял. ?
Это глупость интеловской архитектуры (я уже вроде упоминал, что 8086 -- худший из всех существовавших в конце 1970-х 16-разрядных микропроцессоров; одна из причин такой "лестной" характеристики -- как раз абсолютная неуниверсальность регистров, которые Интел имеет наглость именовать "регистрами общего назначения", хотя у каждого из них есть свои уникальные функции, и ни один не является полноценной заменой другого). Её частично сгладили в архитектуре IA-32 (т.е. в процессоре 80386 и последующих), однако в реальном режиме всё остаётся по-прежнему, да и в 32-разрядном далеко не всё гладко: на кривом фундаменте нельзя построить нормальное здание.
SII Так может я верно считаю, что хоть в L-Mode регистры R8, R9, R10, R11, R12, R13, R14 и R15 по настоящему являются регистрами общего назначения?
s3dworld Более-менее общего, но полноценной "общности" всё равно нет и не будет: тяжкое наследие проклятого прошлого.
SII Как я хочу чтобы они уж сделали всё с нуля. А что получается, что какие-то команды в L-Mode изменяют регистры R8-R15, либо просто не все эти регистры можно применять с какими-то командами?