x86-упрощение
Все инструкции записываются одним байтом без непосредственных данных. Для всех
непосредственных данных существуют свои фреймы. И у каждого блока операций его
дополнительные байты у инструкций читаются не вслед за инструкцией, а из стека
этих данных. Например, вот так:
B8 MOV EAX, 0x00000000
B9 MOV ECX, 1000
00 L:ADD EAX, ECX
E2 LOOP L
E8 CALL MyFunc
C3 RET
...
Frame000:
DD 0x00000000
DD 1000
DB 0xC1
DB 0xFE
DD offset MyFunc
с повышением скорости и понижением цены. Во-вторых, предсказывать переходы уже
будет в сотни раз легче, а значит за такт можно выполнять уже гораздо большее,
значительное количество операций. И т.д.
Конкретный бред?
Конкретный бред?
конечно!
и даже если это не бред, допустим все согласятся что это нужно, что дальше?
Всё началось с моего первого компьютера на базе аналога процессора i8080A. На нём я и учился программированию. А позднее, на Z80.
Если кто знает, все арифметико-логические операции в этих процессорах сохраняют результат в аккумулятор A. А это несколько неудобно. Будучи юношей, с пытливым рассудком и бурной фантазией, я решил "виртуально" доработать систему команд этих процессоров и нашёл коды, которые вероятно нигде не используют. А кодов таких семь. Это пересылка данных из регистра на самого себя. Ну, я использовал их как префиксы и гибкость значительно повысилась:
49 |MOV C,C ; prefix: C as Accumulator
52 |MOV D,D ; prefix: D as Accumulator
5B |MOV E,E ; prefix: E as Accumulator
64 |MOV H,H ; prefix: H as Accumulator
6D |MOV L,L ; prefix: L as Accumulator
7F |MOV A,A ; prefix: using 16-bit
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12 |MOV [BC],A; default
64 12 |MOV [BC],H; with prefix extension
80 |ADD A,B ; default
49 80 |ADD C,B ; with prefix extension
E6 7F |AND A,0x7F; default
52 E6 7F|AND D,0x7F; with prefix extension
Это меня и сделало тем, каким я стал и кем сейчас являюсь. Любитель копаться в машинном коде или системе команд и выискивать упущенные перспективы...
и даже если это не бред, допустим все согласятся что это нужно, что дальше?
А дальше, допустим, это можно использовать в отдельных областях. Например, те же игровые приставки. Функциональность 100% как у x86, но система команд проще. Зачем, скажите, приставке 100% совместимость с PC-приложениями, если на ней запускают в основном разрабатываемые под неё игры? Тем самым, можно поступить и так...
Наверное, проблема не в самом IA-64, а в том, что разработчики i8086 не расчитывали, что этот процессор будет поддерживаться и развиваться на протяжении сорока лет и станет "ПОПСОВЫМ" у всех на столе! И поэтому изначально в самой системе существуют просчёты. Ведь процессор - прежде всего военная технология. Это не ASCII. А у военных они меняются быстро и стандарты там жёсткие не особо то нужны в отношении ПО в машинном коде для управления ракетами или зондами. Там код алгоритма посадки на Марс не будет использоваться и десять лет... :)
Фреймы можно и не переключать. Я нашёл интересное решение.
01 4C|DW 0x4C01
21 |DB 0x21
B8 L:MOV AX,0x4C01
CD |INT 0x21
Ну, чтобы выполнить 10 операций регистр-регистр/память, дешифратору команд легче будет найти команду условного перехода, если все операции будут записаны одним байтом. Тем самым, сама схема нахождения разветвлений очень и очень упрощается и можно легко перейти к трассированию следующих веток.
Просто, если вдуматься, дух захватывает от одной только мысли о том, как может выглядить эта схема на кристалле Intel при такой сложной системе команд. В моём же случае она упрощается в сотни раз. Причём, если начиная с i80486 все операции переводятся в RISC-код, то в моём случае реализацию предлагаемого процессора можно выполнить напрямую без RISC-процессоров и микрокода. Как и было до i80386...
Хочу заметить: Я создал опрос не для того, чтобы все тупо "заценили" мою "гениальную" выдумку. Опрос, прежде всего, для статистики о том кто и как и на каких сайтах относится ко всему из ряда вон выходящему
ну тогда не трать время чтобы убедить нас в том что это круто. Иди убеждай производителей процессоров и приставок.
С радостью! Но, кому писать? Пробовал предложить понятие "Deep"-ячеек виртуальной памяти для ускорения работы с массивами графики и звука, но видно письмо не дошло.
А так, это не круто. А просто расширение возможностей. Вон, сколько операций взгромоздили на бедный префикс 0F!
На правах документации...
Введение:
Процессор имеет два режима работы, которым управляет бит флага TC (Total Compatibility). В режиме полной совместимости бит этого флага должен быть установлен. Приложение может проверить наличие механизма совместимости попыткой отчищения этого бита. Если бит обнуляется, то переход в режим новой системы команд производится отчищением бита привязки к системе команд x86 и переключением к новой.
Добавлена возможность работы над половинками 32-разрядных регистров:
...
EBX = EBH EBL ; EBH - биты 16..31, EBL - биты 0..15 или зеркало BX
66 88 C5 | MOV ECH,EAL(AX) ; Пересылка младших 16 бит EAX в старшие биты ECX
66 18 C6 | SBB EDH,EAL
Вот несколько таких кодов:
00 INT3 Так-как при ошибке управление может передаться на обнулённую область памяти, то этой инструкции самое место данный код. В операционных системах отпадает необходимость в нижнем регионе памяти для отлавливания багов
5? PUSH reg Полная совместимость. Сочетания: 50 5A -> MOV eDX,eAX; 53 5E -> MOV eSI,eBX
5? POP reg Полная совместимость. Сочетания: F9 50 5A -> 66 50 66 5A; F9 53 5E -> 66 53 66 5E
66 DATA32#1 Префикс разрядности данных
67 ADDR32#1 Префикс разрядности адреса
7? Jcc rel Условный переход. Имеется несколько исключений. Могут работать как префиксы для работы над строками
88 MOV rm,r8 Полная совместимость. В сочетании с префиксами DATA32 работают с половинками E?H и E?L
89 MOV rm,r Частичная совместимость. Пересылки регистр-регистр не работают как прежде. Используйте PUSH/POP сочетания
8A MOV r8,rm Частичная совместимость. Пересылки регистр-регистр не работают как прежде. Для этого существует операция 88
8B MOV r,rm Частичная совместимость. Пересылки регистр-регистр не работают как прежде. Используйте PUSH/POP сочетания
B? MOV r8,d Полная совместимость. В сочетании с префиксами DATA32 работают с половинками E?H и E?L
B? MOV r16,d Полная совместимость
CC ADD rm,r8 Перенесена с кода 00
CD INT ib Полная совместимость. Так-как программы не часто изменяют флаг IF, имеются исключения: CD 00 -> CLI; CD 03 -> STI
CE ??? ??? ? Перенесённые инструкции с кода FF
E3 J?CXZ rel Полная совместимость. Исключения: E3 FF -> WAIT;
EB JMP rel8 Безусловный переход. Исключения: EB FE -> HLT; EB FF -> LOCK
F0 REP2 Новые префиксы для повторения операций несколько раз. Подробнее об этом ниже
F4 REP3 Возможны комбинации префиксов: 02 02 -> REP4; 03 02 -> REP5; 03 03 -> REP6
F5 CMC Сочетания: F5 72 FD -> CLC; F5 73 FD -> STC
F8 USED32#1 Сочетание префиксов 0x66 и 0x67
F9 DATA32#2 Эквивалент префикса 0x66 с охватом двух инструкций
FA ADDR32#2 Эквивалент префикса 0x67 с охватом двух инструкций
FB USED32#2 Сочетание префиксов 0x66 и 0x67 с охватом двух инструкций
FF INTO Как и инструкции INT3, этой инструкции тоже присвоен такой код
Как видно, операции, которые используются редко (CLI, STI, HLT, LOCK, WAIT) имеют код не из одного байта, а из комбинаций обычных инструкций в никогда неиспользуемыми режимами.
Так-как в процессоре имеется много дублированных операций, была произведена их сортировка с определением новых функций:
02 D0 | ADD DL,AL -> ADDUSB DL,AL
11 C2 | ADC DX,AX
13 D0 | ADC DX,AX -> ADDSW DX,AX
.............................
89 C2 | MOV DX,AX -> Работают иначе. Возможно, как MOVD
8B D0 | MOV DX,AX -> Работают иначе. Возможно, как MOVQ
75 FF | JNE $-1 -> REPNE ; Аналог стандартного префикса
72 FF | JC $-1 -> REPC ; Расширенные префиксы
...
75 FE 1B D0 | REPNE SBB [DX],[AX] ; Побайтовое вычитание ячеек памяти с насыщением целых(CF=1) и порядковых(CF=0) чисел (PSUBUSB/PSUBSB)
72 FE 88 C2 | REPC MOVSB [DX],[AX]
Операции переходов расширяются префиксами смены разрядности:
67 7? ?? ?? | Jcc rel16 -> аналог 0F 8? ?? ??
2. Прочитать нечто вроде этого Modern Processor Design: Fundamentals of Superscalar Processors
3. Посмотреть в сторону подлинных RISC
Если после этого останется желание продолжить страдать подобного рода идиотизмом пойти и утопиться в унитазе.
PS: Прошу прощения за грубость, однако наличие такого рода сначала любителей, а затем и "профессионалов" как раз и загоняют эту и без того захлебывающуюся собственными испражнениями индустрию.
Не пью, не курю, за юбками не бегаю
Странно, мне её покупать чтоли???
У меня со школьного возраста только RISC'и и выходили в тетрадках :)
И это не поможет...
Согласен. А началось всё с того, что IBM решила вытащить в народ свой PC с i8088, который вообще, если вглядеться в систему команд и архитектуру, не годился в качестве мирового стандарта на настольные ПК. Плюс MS поддержала этот PC. Потом Intel стала в него пытаться "мозги" вкачать побольше. И пошло, поехало... Система команд - хуже отстойника. Хаос и неразбириха. Один префикс 0F чего стоит! Думается, это ошибка гигантов индустрии мирового масштаба. Хуже проблемы "2000"...
Эх, ребята! Не понимаете Вы меня... ;) Кодить охото, а идей нет... Вот и бросает меня в "дрязги" Z80 или x86... Уже файлов 20 на эту тему написал с таблицами за десяток лет... Во-первых, с одной стороны мозги развивает подобные головоломки и стимулирует меня тяга к красоте кода. А во-вторых... Почему разработка процессоров - всегда табу? Дела специалистов? Есть ли вообще коллективы, куда можно влиться и предложить свои идеи?
Вопрос № 2: почему длина команды должна составлять именно 1 байт?
Вопрос № 3: как быть с самым слабым местом архитектуры х86 - явно недостаточным количеством РОН?
Вопрос № 4: о какой программной совмесимости между системой команд переменной длины и системой команд фиксированной длины может идти речь?
PS. Насчет упрощения предсказания переходов - это ты что-то недодумал. Предлагаемая архитектура никак этому не способствует. Проблема не в том, чтобы НАЙТИ команду ветвления, а в том, чтобы начать выполнять следующую команду ПРЕЖДЕ, чем будет получен результат ветвления.
Большая часть настольных вычислительных комплексов базируется сейчас в основном на семействе i80x86... И, я уже говорил, я пытаюсь упростить и систему команд i8080/Z80 в качестве эксперимента и разминки. Но, это мёртвая "линейка"...
Причин много. Для краткости назову одну из них. Вам приходилось в ассемблере сталкиваться с ситуацией, где команда условного перехода недотягивала до метки буквально на 1-3 байта? Т.е. не вписывалась в диапазон $-128..$+127 и приходилось использовать громоздкие расширенные. А в случае однобайтовых команд у нас раздолье буквально до ±127 команд! А не байтов...
Когда я только-только стал осваивать ассемблер-32, был удивлён, что транслятор ругается на команду XCHG EAH,EAL. Друг выручил. Обьяснил, что 16-битные половинки 32-битных регистров просто не предусмотрены, для работы с ними используют SHL Reg32,16 и т.д. Было обидно. Тогда я очень разочаровался в IA-32. Я программировал алгоритмы, где прямая работа с половинками упростило бы всё! Тем более, по идее если первый i8086 был 16-битным и имел богатые возможности для работы с 8-битными половинками, тогда начиная с i80386 ко всему прочему должна была добавлена возможность работы и с 16-битными половинками. Логично! Но мы имеем лишь две половинки 16-битных регистров и младшие половинки 32-битных. Как-то неполноценно. РОН мало, с этим трудно спорить. Но, иногда в цикле не хватает всего одного регистра! И одна та самая половинка могла бы всё исправить. Приходится использовать ячейки памяти, вместо операций сдвига уже и это обидно... Так же, как и с командами перехода. Как-то непродумали как будто.
На уровне ассемблера, а также незначительной переделки компиляторов хватит, чтобы все ЯВУ-компиляторы могли генерировать "однобайтовый" код. Производителям ПО в таком случае нужно будет лишь перекомпилить исходные тексты и всё. Без малейшего изменения исходников. Плюс, существуют отладчики, которые трассируют всю программу и строят древо переходов. Им тоже можно доверить переформировку существующих бинарников в исключительных случаях.
Именно! Скажем, инициация регистров непосредственным данными может производиться за один такт безусловно, а также запись нескольких аргументов в стек. Ветвление всё разбивает. Но, проще, скажем, в идеальном случае, транслировать 127 однобайтовых операций в микрокод напрямую или прошивку внутренней ПЛИС для однотактового выполнения всех 127-и операций, чем разбирать смысл даже двух операций переменной длины!
Когда у меня пользователи спрашивали, как примерно работает процессор, я им отвечал: Берёт байты команд, строит меж-регистровые или вычислительные связи, запускает выполнение, разрушает связи. И так каждый такт. Вопрос: А что мешает построить эти все связи на более длительный период? Сложность машинного языка.
PS: Огромным стимулом послужила статья http://www.forth.org.ru/~drom/forthcpu/misc.html
Вот, решил попробовать доработать уже имеющияся процессоры, как x80 и x86. Причём существует у меня ещё вторая версия x86-команд, где есть 64 префикса как поле ModReg/Mem. Например:
C8 74 -> sete [eax] ; C8 - префикс dst=[eax]; в результате 74 уже работает не как je, а как sete
Скажите это разработчикам компиляторов.
Если уж и разрабатывать оптимизированный процессор, то точно не для разминки ума. Попробуйте придумать CLR-ориентированную архитектуру, или Java-ориентированную. Программы под них даже перекомпилировать не нужно будет! Они уже в переносимом управляемом коде собраны.
1) зайди http://www.intel.com/products/processor/manuals/ и почитай их хорошенько
2) учитывая размер шины данных, нах загружать инструкции такими пачками по байту, если в реальных приложениях очень велика вероятность дальних переходов, опять же при этом должен сработать механизм переключения фрейма... да ну это только на сонную голову подумаю сколько заморочек возникает, утром еще посмотрю... а при большом количестве ветвлений с переходами (возьми любое нормальное приложение, а не свой хелло ворлд в фасме) так вообще бредятина с фреймами получается, процессор большую часть времени только думать будет какой фрейм ему загрузить следующим, а вместе с ним и кучу дерьма, которое вполне возможно при определенных условиях в функции не понадобится... какая там к чертям производительность... а предсказаниями тут и вообще не пахнет...
3) int 03 дать код 00 потому-что в нижних регионах ось отлавливает баги... слушай это вообще на баш можно отправить... у тя не только с системой комманд проблемы, ты и с арх-рой х86 не дружишь ... видишь ли есть такой в процессоре защищенный режим, так во время работы в нем на сегменты устанавливаются уровни привилегий, их 4 но обычно используют только 2... ну так вот на тех нижних регионах обычно стоит 0 уровень и когда код пользовательского режима пытается исполнить, прочитать или записать туда че-нить, возникает общее исключение защиты и управление передается обработчику, который установила ось или попросто оси... и никакой инт3 там нах не нужен и каким образом ты бушь баг отлавливать, допустим в ситуации, что в проге написанной на с++ в какой-то момент не произошло создание объекта и следующий код попытался прочитать из него, допустим из поля со смещением а3, в твоем случае он просто получит содержимое 0xa3 и хули толку с твоего инт3 даже если там нули, исполнять то он его не будет?.... опять же читай пункт 1
4) короче аффтар начни курить, пить и бегать за юбками... поверь очень полезно для мозгов... а не то рискуешь закончить разработками процессоров в палате оббитой матрацами...
p.s. сорри за корявость мыслеизложения... 4 утра и я хочу спать писать фпадлу, читать тоже... высплюсь попробую выложить более конструктифно...
Спасибо!
Вы так говорите, потому что существующие средства разработки, опыт и компиляторы адаптированы под существующую систему команд неопределённой длины. Хотя, если посмотреть на "войну" Watcom C, Intel C и прочих средств, система команд до сих пор еле еле даётся зубам монстрам индустрии. О чём это говорит? Система через чур путанная. Наверное, это самая уродливая система команд, которая выжила в процессе вычислительной эволюции. Не без помощи IBM и MS, которые, опять-таки повторяю, посмели вытащить x86 в народ и быт. Плюс, будте добры, дайте ссылку на страничку, где говорится, что в таком-то году разрабатывался процессор с подобной системой команд и стал тупиковой веткой? Просто, мне очень интересно будет изучить его архитектуру. А так, Ваши слова столь же не оправданы, как и не оправдан мой труд в этом направлении. ;)
3) int 03 дать код 00 потому-что в нижних регионах ось отлавливает баги... слушай это вообще на баш можно отправить... у тя не только с системой комманд проблемы, ты и с арх-рой х86 не дружишь ... видишь ли есть такой в процессоре защищенный режим, так во время работы в нем на сегменты устанавливаются уровни привилегий, их 4 но обычно используют только 2... ну так вот на тех нижних регионах обычно стоит 0 уровень и когда код пользовательского режима пытается исполнить, прочитать или записать туда че-нить, возникает общее исключение защиты и управление передается обработчику, который установила ось или попросто оси... и никакой инт3 там нах не нужен и каким образом ты бушь баг отлавливать, допустим в ситуации, что в проге написанной на с++ в какой-то момент не произошло создание объекта и следующий код попытался прочитать из него, допустим из поля со смещением а3, в твоем случае он просто получит содержимое 0xa3 и хули толку с твоего инт3 даже если там нули, исполнять то он его не будет?.... опять же читай пункт 1
Знаю. Но, когда я программировал ещё на ПК советской эпохи, на базе аналога i8080A, где 00 - код операции NOP (Z80 смотрите), то при переходе на пустую с нулями область процессор тупо по всем 00 и бежал, пока не натыкался на какой-нибудь код. Тут и появился вопрос: Почему 00 - не HLT?
Возьмём VisualStudio C++ и запустим своё приложение на отладку. В начале каждой функции при дизассемблировании можно видеть цикл, заполняющий стек словами 0xCCCCCCCC. Ну, CC - и есть INT3, а отладчик использует его в своих целях. Так вот тут опять возникает вопрос, что логичнее было бы обнулить стек, а не цок-цокать, если бы 00 был бы INT3. Так что тут дело даже не в самом механизме защиты, а суть идёт ближе к эстетике! Понимаю, CC - красивый код, но 00 - куда красивее, а главное - логичнее! 0 - конец всего! Пусто! А на самом деле 00 что? ADD [EAX],AL до опупения!!!
Прощу прощения, если был груб...
Возьмём эмулятор платформ, отличных от PC. Скажем, эмуляторы Sony-PSX, Sega, Dendy, ZX-Specturm. Например, в Dendy процессор 6802, в Sega - 68000, ZX-Spectrum - Z80 и т.д.
Когда начинаешь вдумывать в механизм эмуляции этих процессоров, виден маразм: Практически каждая из "примитивных" инструкций тех процессоров, которые реализовывались несколькими тысычами транзисторов в оригинале, переводятся в сотни x86-инструкций, т.е. задействуют аппаратно такой объём электронной начинки в x86, который бы хватило на тысячи оригинальных тех процессоров!!!
Это сравнимо с тем, чтобы выполнить X = Y ^ Z мы будем использовать чистую математику:
double Z = 0.0f, mlt = 1.0f, tmp;
for(int i = 0; i < 32; i ++) {
X /= 2.0f; Y /= 2.0f; Z /= 2.0f; mlt *= 2.0f;
tmp = X + Y; tmp = tmp - floor(tmp);
Z += tmp * mlt;
}
return Z;
}
Тогда как если бы в Dendy написали эмулятор i8086 и одну его инструкцию эмулировали бы 100 инструкций 6802, то это было логичнее. Ведь начиная с 486 каждая его инструкция переводится в десяток микрокода внутреннего RISC-процессора. Что правильно...
О чём это говорит? Думаю, никто не замечает или не хочет замечать тот кризис, в котором сейчас находятся современное поколение компьютеров.
Процессор Эльбарус своим кодом эмулирует Pentium и обгоняет его, хотя частота ниже и интеграция проще. Это замечают сторонники RISC и MISC, используя это как основной аргумент в пользу простого. Но!
Эта тема увлекла и меня. Отчего я занялся упрощением x86 в сторону однобайтовых команд, как Вы поняли. Однако, сложно упростить развитое прошлое. Всё равно, что упрощать Русский Язык для лучшего понимания иностранцами и электронными переводчиками. Для этих целей когда-то разработали Esperanto. Сейчас их расплодилось же очень много... А толку то?
Сейчас я занимаюсь разработкой своего процессора с простейщей системой команд (три десятка групп), в которой нет префиксов и все команды однобайтовые. Занимаясь этим, я заметил одну интересную вещь: стоит выбросить одну группу, и написание кода усложняется или вовсе попадает в тупик. Т.е., как говорится, простота имеет тоже свои границы.
Эмулятор написан прямо в html как js и выводит дамп памяти, стека и всех команд. Дубовая работа. :) Но она необходима для того, чтобы попытаться в том коде на примитивных командах реализовать затем эмулятор IA-32. В качестве опыта...
Вопрос не в этом.
Существует 2 варианта:
1. Существующая система команд, под которую УЖЕ написана масса софта.
2. Проектируемая система команд, под которую еще ничего нет, но которая имеет существенные преимущества перед 1.
Так вот, во 2 случае имеет смысл не опираться на 1, а делать систему команд с нуля в соответствии с теми принципами, которые в нее требуется заложить.
И что, есть какая-то принципиальная разница между 127 байтов и 127 команд? Или во втором случае существует гарантия, что нам не потребуется сделать переход на 129 команд?
Да и вообще странно, ратуя за однобайтные команды, приводить в пример двух байтную.
Опять же, ты отвечаешь совсем не на тот вопрос, который был задан.
Чем однобайтная команда лучше, скажем, 4-байтной или 8-байтной?
Да, когда столкнулся с этим, тоже был несколько разочарован. Но после некоторого размышления пришел к выводу, что выбран ОПТИМАЛЬНЫЙ вариант.
А если не хватает двух, причем паолноразрядных?
Следует искать решения, которые УСТРАНЯЮТ проблему, а не позволяют решить ее в отдельных частных случаях.
А нас интересует именно легкость адаптации компиляторов или все-таки эффективность работы процессора?
Сейчас мы сделаем маленький шажок вперед, который, тем не менее, заставит нас переделывать ВСЕ существующее ПО. Затем возникнет необходимость еще одного маленького шажка и т.п.
Не лучше ли сразу разработать революционную систему команд, учитывающую все новейшие достижения в этой области?
А то вспоминается анекдот: хозяин очень жалел свою собаку, поэтому купировал ей хвост маленькими кусочками.
По поводу записи нескольких элементов в стек - крайне сомнительное утверждение. За 1 такт даже 1 байт в память не запишешь, не то что последовательность, превышающую ширину шины.
Логичнее транслировать 256 операций по первому байту команды фиксированной длины, раз уж заранее известно, с какого смещения начинается код каждой команды.
Недостаток команд переменной длины состоит в том, что нельзя определить адрес начала следующей команды, пока не декодирована предыдущая.
Не сложность, а внутренне недостатки системы команд.
Кстати, советую почитать что-нибудь об IA-64. Там очень много "вкусностей", которые тебе с твоим подходом даже и не снились. Тем не менее, не пошла. Несмотря даже на целый ряд очень интересных и полезных решений. И на авторитет самой Intel.
Существует 2 варианта:
1. Существующая система команд, под которую УЖЕ написана масса софта.
2. Проектируемая система команд, под которую еще ничего нет, но которая имеет существенные преимущества перед 1.
Так вот, во 2 случае имеет смысл не опираться на 1, а делать систему команд с нуля в соответствии с теми принципами, которые в нее требуется заложить.
Пробую. Это и делаю. Но, получает Forth-подобие. Уже лет 13 бьюсь, а успехи мизерные...
Да и вообще странно, ратуя за однобайтные команды, приводить в пример двух байтную.
Опять же, ты отвечаешь совсем не на тот вопрос, который был задан.
Чем однобайтная команда лучше, скажем, 4-байтной или 8-байтной?
Хм. В процессоре Sony PSX одна команда - четыре байта. Я и два байта рассматривал. Мало байтов - данным места нет, много байтов - простую операцию не реализуешь, т.к. избыток и трата памяти. От чего у меня и вариант: REPNZ -> JNZ $-2 в "нормальной" системе команд. Ведь выбросили же в IA-64 команды AAM/AAD и прочие ненужные. В моём варианте Jcc $-2 заменяют REPcc, т.е. и освобождают два кода, и в то же время расширяют префикс.
Наверно, до Вас мне далеко. Это комплимент...
Следует искать решения, которые УСТРАНЯЮТ проблему, а не позволяют решить ее в отдельных частных случаях.
Эммм... Какрас-таки таких "частных" и накапливается тысячами. Проблема 2000 тоже появилась из-за того, что программисты не расчитывали, что их частный хлам будут использовать в течение четверти века!
Сейчас мы сделаем маленький шажок вперед, который, тем не менее, заставит нас переделывать ВСЕ существующее ПО. Затем возникнет необходимость еще одного маленького шажка и т.п.
Не лучше ли сразу разработать революционную систему команд, учитывающую все новейшие достижения в этой области?
А то вспоминается анекдот: хозяин очень жалел свою собаку, поэтому купировал ей хвост маленькими кусочками.
Тогда, возвращаясь к прошлой теме моей, нужен уже процессор с открытыми символическими командами (см. Проц. будущего)
Так ведь процессор должен смотреть. Если в стек пишется один регистр, а за тем сразу читается -> MOV. Т.е. стек уже игнорируется и выполняется за один такт. Разве механизмы выполнения нескольких команд за такт так не поступают?
pop ds es
Недостаток команд переменной длины состоит в том, что нельзя определить адрес начала следующей команды, пока не декодирована предыдущая.
Ну, да. С другой стороны 128 - мой пример(!), а не повод "цепляться";)
Кстати, советую почитать что-нибудь об IA-64. Там очень много "вкусностей", которые тебе с твоим подходом даже и не снились. Тем не менее, не пошла. Несмотря даже на целый ряд очень интересных и полезных решений. И на авторитет самой Intel.
Авторитет Intel... Я уже говорил, что Intel запятнала себя, когда дала добро на "i8088 в народ!".
А сейчас Pentium - это старикашка i8088 в больших и, извиняюсь, полностью пр*ср*тых полных подгузниках. А в i80x86 знак x - номер подгузника поверх предыдущих. Реанимация затянулась и без противогаза не обойтись...
Ну, выкинули там AAM и что? Равносильно тому, что иглой прокололи памперс, чтобы хоть чуточку снизить давление...
P.S. Одно время мучал вопрос: Почему при разработке IA-32 и 64 они полностью унаследовали предыдущую? Ведь вполне можно в режиме 16 использовать дедушкину систему команд 86, а в режиме 32 или 64 - совершено новую. Это ничем не повредит же. Хотя, тут много ньюансов. Но технологически! Это проще. Скажем так:
8086) 8086
80386) 80286 + новый 80386. Два процессора в одном.
Что получаем? Вот IA-64 унаследовала все ошибки IA-32, а IA-32 - ошибки IA-16. Как уже говорили: Windows'98 забрался на DOS, а Windows'NT повесил себе на шею Windows'98 и DOS. Ну, примерно так...
Так вот. Что мешает им при разработке нового процессора внедрить в кристалл предыдущий + новый не совместимый? Не было бы заплаток на заплатках. Тем более, это бы всего лишь отразилось на микрокоде. И всё! Первая страница микрокода - команды IA-16, вторая - IA-32, и т.д. А они поступили так, будто разработать абсолютно новый транслятор - очень тяжело... Или заботятся о кодерах-любителях на уровне кода? ;) По крайней мере, я не понимаю прикола.
Раньше, вон, компьютеры, типо Apple с каждым разом строились на новом процессоре и были не совместимы друг с другом. Хотя, эту проблему можно было бы решить внедрением в компьютер и старого процессора наряду с новым через "контроллер совместимости".
Например, не думаю, что будет очень тяжело в PC-материнку вместе с Pentium внедрить и реальные Z80 и 68000. Да, архитектуры очень различные. Но, через контроллер тем можно назначить свои окна в памяти и т.д...
На дворе 2008 год. Такое было в первых процессорах. причем в 8086 уже связи были и не рушились. Так что советую почитать про архитектуру современных процесоров.
Цитата:
Сообщение от andriano
По поводу записи нескольких элементов в стек - крайне сомнительное утверждение. За 1 такт даже 1 байт в память не запишешь, не то что последовательность, превышающую ширину шины.
Код:
push cs cs
pop ds es
А это тут причем? Был вопрос про запись. Что касается Push PoP то советую опять таки почитать про архитектуру. Все там есть.
Так вот. Что мешает им при разработке нового процессора внедрить в кристалл предыдущий + новый не совместимый?
Ты вначале в терминах разберись. В IA-64 как раз так и сделали не пошли процессоры. А мешает то что микро код был бы не таким уж микро это раз. Два эмулирование тормазилобы всю систему. Ну ладно если не брать все механизмы процессора тогда да одна система команд. Ну так так и сделана. Еще раз говорю изучайте архитектуру.
Был у меня один прожект. Разрабатывал процессор со своей системой команд. Выложил на форум, а мне задали вопрос:
--- Постой-ка. А где флажки привелегий? Где регистры?
--- Ну, так у меня же не x86. Зачем оно тут надо? Здесь это не так работает...
--- Так, тогда бросай! Все компании-разработчики из кожи вон лезут, чтобы добиться совместимости с x86-линейкой!
А процессор был таким:
Система команд нефиксированной длины. Разбита на несколько страниц. Каждая страница переключается префиксом на одну команду или полностью. На каждой из страниц имеются команды определённого назначения:
1) Команды ОС, ОС-API. Т.е. приложение через них общается с системой. Для самой же системы страница состоит из привелегированных команд;
2) Вычислительные команды. Здесь имеются команды работы с АЛУ и FPU, а также и ОС-дополнения/эмуляция;
3) Команды работы с данными. Работа с таблицами, стеком, ассоциативными массивами, файловой системой и т.д.;
4) Команды организации функций и процедур, назначение меток для сообщения с ОС;
5) Команды API-среды. Все приложения могут сообщаться друг с другом через инструкции этой страницы. Доступ к архиваторам, компиляторам и т.д.;
6) Команды работы с устройствами. Доступ к видеоконтроллерам, аудиокартам, клавиатурам, к другим процессорам;
7) Собственная библиотека инструкций каждого из приложений локального пользования;
8) Команды, сформированные Программируемой Логической Матрицей.
В общем, система команд наращиваемая и достаточно гибкая.
Например, команды гр. 6 имеют прямой доступ к видеокартам и т.д. Однако, видеокарта в таком случае имеет собственный интерфейсный процессор, который смотрит, может ли он сам выполнить инструкцию такого-то приложения. В противном случае, центральному процессору будет послан сигнал "исключения" (термин x86 для данного поста), чтобы ОС исправила ситуацию. Т.е. "железо" в этой системе довольно высокого уровня. Где SVGA карточку, например, подключаем через дополнительный сопроцессор. Сложно? Дорого? Вопросы для анализа...
Над этим процессором я "потел" лет 5. Пока не опубликовался на форуме и понял, что всё - дрянь...
Теперь я, чтобы не сидеть без дела, и пытаюсь модифицировать x86-команды...
P.S. Хотя вру. Идея того процессора переродилась в ОС без явного API, о которой я говорю в соседней теме...
Зачем нужны кманды для работы с фаловой ситемой? Зачем нужны коанд работы с видео? У видео карты свой проц. Он отдельный, пусть они работают в едином адрестном пространстве и все.
Что требуется от проца? Простота команд и паралельность и чтобы это все шустро работало без задержек. Делаем простую вещь 3 команды and or not. Делаем кучу исполнительных блоков. Которые расположены последовательно паралельно.
В каждый такой исполнительный блок податся команда. Вернее две команды и два набора данных. Делаем пару флаг которые выбирают какую кманду использовать и какие данные. А именно те что пришли с соседнего блока или те что были заложены изначально. Проц предпологалось делить на два участка. Один исполнительный. Другой тоже. Но на нем вертиться код который разбирает систему команд x86 и оптимизирует ее. Кэш не предпо логалось, предпологалосб что декодер расположен паролельно и именно он управляет переключениями. Хотя тут возможно поступить иначе ввести кэш. Но дальше я не стал прорабатывать.
Зачем нужны кманды для работы с фаловой ситемой? Зачем нужны коанд работы с видео? У видео карты свой проц. Он отдельный, пусть они работают в едином адрестном пространстве и все.
Что требуется от проца? Простота команд и паралельность и чтобы это все шустро работало без задержек. Делаем простую вещь 3 команды and or not. Делаем кучу исполнительных блоков. Которые расположены последовательно паралельно.
В каждый такой исполнительный блок податся команда. Вернее две команды и два набора данных. Делаем пару флаг которые выбирают какую кманду использовать и какие данные. А именно те что пришли с соседнего блока или те что были заложены изначально. Проц предпологалось делить на два участка. Один исполнительный. Другой тоже. Но на нем вертиться код который разбирает систему команд x86 и оптимизирует ее. Кэш не предпо логалось, предпологалосб что декодер расположен паролельно и именно он управляет переключениями. Хотя тут возможно поступить иначе ввести кэш. Но дальше я не стал прорабатывать.
Либо я Вас не понял, либо Вы меня... ;)
1) Страница инструкций работы с файловой системой (их 224 всего) нужны для организации API. Скажем, в x86 команды FPU встроены как родные и работают так же с памятью, как и обычные команды. Плюс, параллеризм. В моём процессоре похожая логика. Если в системе есть настоящий интеллектуальный файловый контроллер, приложениям он сам будет искать и назначать файлы. Если же такового нет, ОС его будет эмулировать;
2) Команды работы с видео нужны также для организации интерфейса. Если карточка интеллектуальная, она сама распределит доступ к региону видеокадра (графического окна). Сама построит ломанные или 3D-поверхности. Если же нет, ОС опять-таки будет эмулировать работу.
Т.е. примерный код работы с файлом/графикой такой:
20 33 45 78|Unit '3Dx' ; Выбераем устройство работы с 3D-графикой
96 EA 17 54|Sphere 0xEA, 23, Reg[4] ; В данном устройстве код 96 - вывод сфера
20 46 53 78|Unit 'FSx' ; Переключаемся на файловый контроллер
96 56 |FindFirst Reg[6] ; В данном устройстве код 96 - поиск файла
И ещё. Вы здесь путаете архитектуру моего процессора с x86. ;)
Этот вариант процессора ближе к RISC.
Например, может быть так:
65..7E - Регистры A..Z
7F - [Stack]
80 - NOP
81 - -[Stack]
82..9B - Регистры -A..-Z
9C..FF - Величина -100..-1
30 66 67 01|AND Reg#B, [Reg#C+1]
30 67 66 80|AND Reg#C, Reg#B
30 7F 7F 01|AND Stack, Stack[+1]
На самом деле, систему команд этого процессора я разрабатывал с 17-ти лет. И сотни раз перерабатывал. В последний раз занимался ею лет 5 назад (до постов на том форуме), а потом забросил.
Понимаю Вашу иронию.
Тем не менее, на осмысление этого факта мне действительно потребовалось время, и изложить аргументацию в 2-3 абзацах просто не получится.
Тем не менее, существует общее решение пролемы и частное - т.е. "заплатка". Частное - все попытки увеличить диапазон действия "короткой" команды. Общее - избавиться от дублирования команд и оставить лишь ту, которая позволяет осуществлять переход в пределах всего адресного пространства.
Другими словами, полностью избавиться именно от той команды, которую Вы предлагаете усовершенствовать.
pop ds es
Это метедологически неверная точка зрения.
Проблема проистекает из того, что снаружи у процессора одна система команд, а внутри - другая. И мы сетуем на то, что он недостаточно эффективно транслирует одну в другую.
А он не должен желать этого ВООБЩЕ!
Ведь именно на трансляцию он тратит существенную часть своей вычислительной мощности. Следовательно, процессор должен получать от компилятора такие команды, которые бы не нуждались ни в какой оптимизации. А если уж они неоптимальны, значит, выполнять неоптимальные, а не пытаться их оптимизировать.
Другое дело, что сама система команд i86 такова, что ее невозможно выполнять быстро. И это проблема, которая не решается косметическими ухищрениями.
Я, конечно, не Intel, но мне, тем не менее, очевидно, что модель 8086 была разработана в качестве переходной от 8- к 16-разрядным компьютерам с целью олегчить адаптацию программ, написанных на 8-разрядном Ассемблере. То, что именно этот процессор будет выбран IBM для своего ПК, а сам этот ПК станет стандартом де-факто, никто не предполагал.
Что ж, теперь, понятна причина недопонимания.
Итак:
IA-64 - это Itanium, т.е. процессор с фиксированной длиной комады, умеющий программно-аппаратно эмулировать систему команд x86. Сами команды не имели ничего общего с x86, в частности, распараллеливание команд было предусморено еще на уровне компилятора.
Не следует путать IA-64 с AMD-64, которая и нашла свое распространение в современных Core и Athlon-64. В то время как IA-64 умирает вместе с Itanium.
Но, собственно, те соображения, которые Вы приводите, как раз и взяты в ее основу (и много чего еще другуго).
Таким образом, при переходе от IA-16 к IA-32 система команд "внутри" и "снаружи" еще была одной и той же, кроме того, небольшое количество транзисторов на кристалле не позволяло уместить там два разных процессора, по сути дела процессор-то был один, 32-разрядный, а 16-разрядность эмулировалась при помощи того же механизма, который в 32-разрядном режиме осуществлял защиту. Т.е. все очень экономно.
А при переходе от IA-32 к IA-64 Intel попыталась радикально измениь систему коман. Благо, к тому моменту это уже назрело.
Но не вышло... Зато вышло у AMD, которая тупо расширила существующую IA-32 на 64 разряда почти так, как это было сделано на этапе перехода от IA-16 к IA-32.
PS. Советую перечитать несколько постов назад: с пониманием разницы между IA-64 и AMD-64 многие мои утверждения станут понятнее.
Таже самые команды только проще.
mov al,9 // Вывод сферы
out dx,al // послать команду
out это костыль 86 обычно порты отображают в едино пространство памяти, так сейчас работает все современное железо жестки видео и тд.
mov al,9 // Вывод сферы
mov [dx],al // послать команду
И процу нужно разбирать только одну команду и проверять dx. Если устройство есть передаем команду нет эмулируем. Так работает NTVDM (виндовский эмулятор доса). Но это для поддержки старых программ.
Но тут неудобно передавать параметры поэтому в виндоусе с незапамятных времен появились библиотеки.
И формат команды изменился на
push y
Call DrowBox
Тут есть плюс. Адрес DrowBox береться при загрузке/компиляции. Поэтому нет фиксированного адрес есть только имя. Теперь в системе может быть различное наполнение. Хочешь две видео карты пожалуйста. Хочешь 10 жестких пожалуйста. У каждого устройства своя база. Тем самым память используется более рационально.
В месо базы используется ссылка в простонародье handle.
push x
push y
Call DrowBox
Но тут минус в том что есть слои абстракции. Которые тормозят. Следующий шаг это NET. Умный компилятор-исполнения должен заменить все эти call и push на обращения к конкретным устройствам. Он должен с оптимизировать код звписав его в кэш. Но это возможно только для стационарных объектов. А вот для динамических тут время на оптимизацию может превосходить время жизни объекта. Вторая особенность это то что компилятор-исполнения знает какой у нас проц и железо он может лучше подобрать систему команд для оптимизации. Выполнить распараллеливание кода между ядрами.
компилятор-исполнения - это компилятор который компилирует код при его за пуски на платформе пользователя.
Таже самые команды только проще.
mov al,9 // Вывод сферы
out dx,al // послать команду
out это костыль 86 обычно порты отображают в едино пространство памяти, так сейчас работает все современное железо жестки видео и тд.
mov al,9 // Вывод сферы
mov [dx],al // послать команду
И процу нужно разбирать только одну команду и проверять dx. Если устройство есть передаем команду нет эмулируем. Так работает NTVDM (виндовский эмулятор доса). Но это для поддержки старых программ.
Да? А давайте и FPU-инструкции вынесим в порты? Может, тоже проще станет?;)
То порты - это проще, а то - костыль. Вас как понимать? ;)
И формат команды изменился на
push y
Call DrowBox
Тут есть плюс. Адрес DrowBox береться при загрузке/компиляции. Поэтому нет фиксированного адрес есть только имя. Теперь в системе может быть различное наполнение. Хочешь две видео карты пожалуйста. Хочешь 10 жестких пожалуйста. У каждого устройства своя база. Тем самым память используется более рационально.
В месо базы используется ссылка в простонародье handle.
push x
push y
Call DrowBox
А вот в моей архитектуре каждое новое устройство подключается к процессор не как порт или ячейки памяти, а на уровне команд как новый набор инструкций со строгим протоколом и системой. Между прочим FPU-инструкции не очень-то вписываются в систему x86-команд на уровне мнемоники...
Это у тебя провал в знаниях. Ты же не знаешь что такое MMIO.
Костыль OUT, а не порты. Мухи отдельно котлеты отдельно.
Команды вычисления нужны в памяти я уже объэтом писал. А вот запуск исполнения можно вынести в порты. Но нужна синхронизация, но она и так есть fwait. Но для универсальности лучше сделать симофор для выбраной ячейки. И чтобы команды для работы с ним поддерживались аппортно.
Это еще более универсально, хотим ждем выполнения команды не хотим выполняем свои. Нету жесткой привязки.
Костыль OUT, а не порты. Мухи отдельно котлеты отдельно.
Команды вычисления нужны в памяти я уже объэтом писал. А вот запуск исполнения можно вынести в порты. Но нужна синхронизация, но она и так есть fwait. Но для универсальности лучше сделать симофор для выбраной ячейки. И чтобы команды для работы с ним поддерживались аппортно.
Это еще более универсально, хотим ждем выполнения команды не хотим выполняем свои. Нету жесткой привязки.
Буду считать, что этой темой я проверял свои знания...
16 лет программисткой практики моей ничего не стоит. Я это только сейчас твёрдо понял...
Чтож... Пойду писать и оптимизировать свой очередной Hello world! ;)