Forth и другие саморасширяющиеся системы программирования Locations of visitors to this page
Текущее время: Сб май 21, 2022 12:29

...
Google Search
Forth-FAQ Spy Grafic

Часовой пояс: UTC + 3 часа [ Летнее время ]




Начать новую тему Ответить на тему  [ Сообщений: 39 ]  На страницу Пред.  1, 2, 3  След.
Автор Сообщение
 Заголовок сообщения:
СообщениеДобавлено: Ср май 30, 2007 17:28 
Не в сети

Зарегистрирован: Сб май 06, 2006 18:43
Сообщения: 400
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
вопрос писал(а):
насколько я понимаю, многие процессоры, особенно х86 не сообенно экономят на размерах команд, для чего же экономить тут?

тут экономия на скорости -- если для 80х86 использовать побайтное чтение/запись со сдвигами и наложениями, то на каждый call который в шитом коде программы без оптимизации не меньше 90%, получается бесполезная потеря времени на выборку параметра call/jmp (хотя не спорю что если не использовать указатели, код получается куда нагляднее)

_________________
http://akps.ssau.ru/forth/


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Ср май 30, 2007 17:30 
Не в сети

Зарегистрирован: Сб май 06, 2006 18:43
Сообщения: 400
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
in4 писал(а):
Получается, чем лучше упакована система команд - тем больше максимальный размер программы... :)

тут еще можно учесть то, что компактного байт-кода больше влезет в кеш данных, а движок так вообще можно постараться целиком в кеш команд впихнуть (а может даже и стараться не надо, оно само впихнется -- может кто точнее знает как современные интелоиды работают)

_________________
http://akps.ssau.ru/forth/


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Ср май 30, 2007 17:33 
Не в сети

Зарегистрирован: Сб май 06, 2006 18:43
Сообщения: 400
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
in4 писал(а):
ВМ можно встроить в микроконтроллер, у которого ресурсов маловато.

А для микроконтроллеров у ВМ еще одна фича есть -- сам контроллер работат как форт-процессор, а программы храним во внешней памяти, флеш-карте, винте. И для отладки рай -- если контроллер не самый хилый, в движок можно напхать отладочный функций

_________________
http://akps.ssau.ru/forth/


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Вс июн 03, 2007 09:59 
Не в сети

Зарегистрирован: Сб май 06, 2006 18:43
Сообщения: 400
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
минимальное дополнение к исходнику движка, чтобы работало EMPTY:

Код:
// сишный "микрокод" команд ВМ

void nop() { }
void jmp() { Ip=Mget(Ip); }
void bye() { exit(0); }


Код:
void step()
{
// выборка команды с проверкой сто не улетели вне адресного пространства
assert(Ip<Msz); op=M[Ip++];
// запуск "микрокода" команды на Си по ее опкоду
// быстрее и красивее таблица указателей на "микрокод" команд ВМ с индексацией
// по опкоду команды, но менее наглядно и недоступно в некоторых языках
switch(op) {
            case 0x00: nop(); break;
            case 0x01: jmp(); break;
            case 0x07: bye(); break;
            default:
                    #ifdef MODE16
                         fprintf(stderr,"\nCORE %.4X:%.2X\n",--Ip,op);
                    #else
                         fprintf(stderr,"\nCORE %.8X:%.2X\n",--Ip,op);
                    #endif
                    abort();
}
}

_________________
http://akps.ssau.ru/forth/


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Вс июн 03, 2007 12:01 
Не в сети

Зарегистрирован: Сб май 06, 2006 18:43
Сообщения: 400
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Описал в форуме самую сложную часть целевого компилятора -- структуры управления (это инфы даже в книге см. таглайн) еще нет.

Теперь осталось добить исходник движка и определения опкодов команд в ЦК. Далее будут куски сишного кода движка и соответствующие им строки, которые надо добавить в TC.4th. Абсолютно ничего сложного, должно читаться с ходу, особенно если учесть что многозадачности пока нет (но будет -- оказалась очень удобной фичей при написании программ, реализуется в виде нитей, для чисто программной реализации при интерпретации как два пальца реализовать, но исходник движка несколько усложняется переключением процессов и добавляется большой кусок кода использующий несходупонимаемые указатели)

_________________
http://akps.ssau.ru/forth/


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Вс июн 03, 2007 12:04 
Не в сети

Зарегистрирован: Сб май 06, 2006 18:43
Сообщения: 400
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
команды управления ходом выполнения (control flow) полный комплект:

Код:
void nop()   { }
void jmp()   { Ip=Mget(Ip); }
void qjmp()   { assert(Dp>=1); if (D[--Dp]) Ip+=CELL; else jmp(); }
void call()   { assert(Rp<Rsz); R[Rp++]=Ip+CELL; jmp(); }
void ret()   { assert(Rp>=1); Ip=R[--Rp]; }
void lit()   { D[Dp++]=Mget(Ip); Ip+=CELL; }
void bye()   { exit(0); }


Код:
void step() {
switch(op) {
            case 0x00: nop(); break;
            case 0x01: jmp(); break;     case 0x02: qjmp(); break;
            case 0x03: call(); break;    case 0x04: ret(); break;
            case 0x05: lit(); break;
            case 0x07: bye(); break;


Код:
0x00 0op nop
0x01 1op jmp      0x02 1op ?jmp
0x03 1op call      0x04 0op ret
0x05 1op lit   : # lit ;
0x06 0op exec
0x07 0op bye

_________________
http://akps.ssau.ru/forth/


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Вс июн 03, 2007 12:09 
Не в сети

Зарегистрирован: Сб май 06, 2006 18:43
Сообщения: 400
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
циклы do/loop используют спец.команды и свой отдельный стек

Код:
struct DOLOOP {      // стек do/loop
   int count,max;
   uint addr;
} L[Lsz]; uint Lp=0;


к именам команд добавлена буква z так как совпадают с сишными ключевыми словами

Код:
void zdo()   { assert(Lp<Lsz); assert(Dp>=2);
        L[Lp].addr=Ip; L[Lp].count=D[--Dp]; L[Lp].max=D[--Dp]; Lp++; }
void zloop()     { assert(Lp>=1); L[Lp-1].count++;
        if (L[Lp-1].count==L[Lp-1].max)   Lp--;
        else               Ip=L[Lp-1].addr; }
void zi()   { assert(Dp<Dsz); assert(Lp>=1); D[Dp++]=L[Lp-1].count; }
void zj()   { assert(Dp<Dsz); assert(Lp>=2); D[Dp++]=L[Lp-2].count; }
void zk()   { assert(Dp<Dsz); assert(Lp>=3); D[Dp++]=L[Lp-3].count; }


Код:
void step() {
switch(op) {
            case 0x08: zdo(); break;     case 0x09: zloop(); break;
            case 0x0A: zi(); break;      case 0x0B: zj(); break;


Код:
\ команды для циклов do/loop

0x08 0op do   0x09 0op loop   0x0A 0op i   0x0B 0op j   0x0C 0op k

_________________
http://akps.ssau.ru/forth/


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Вс июн 03, 2007 12:14 
Не в сети

Зарегистрирован: Сб май 06, 2006 18:43
Сообщения: 400
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
стековые операции

Код:
void dup()    { assert(Dp>=1); assert(Dp<Dsz); Dp++; D[Dp-1]=D[Dp-2]; }
void drop()   { assert(Dp>=1); Dp--; }
void swap()   { assert(Dp>=2); int t=D[Dp-1]; D[Dp-1]=D[Dp-2]; D[Dp-2]=t; }
void over()   { assert(Dp>=2); assert(Dp<Dsz); Dp++; D[Dp-1]=D[Dp-3]; }


Код:
void step() {
switch(op) {
            case 0x10: dup(); break;     case 0x11: drop(); break;
            case 0x12: swap(); break;    case 0x13: over(); break;


Код:
0x10 0op dup   0x11 0op drop   0x12 0op swap   0x13 0op over

_________________
http://akps.ssau.ru/forth/


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Вс июн 03, 2007 12:22 
Не в сети

Зарегистрирован: Сб май 06, 2006 18:43
Сообщения: 400
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
операции с памятью (пока без XMEM команд -- надо еще прорабатывать)

для memmove надо добавить

Код:
#include <mem.h>


Код:
void Cfetch()    { assert(Dp>=1); uint addr=D[--Dp]; assert(addr<Msz);
                  D[Dp++]=M[addr];                                        }
void Cstore()    { assert(Dp>=2); uint addr=D[--Dp]; uchar byte=D[--Dp];
                  assert(addr<Msz); M[addr]=byte;                         }
void fetch()     { assert(Dp>=1); uint addr=D[--Dp]; assert(addr<Msz);
                  D[Dp++]=Mget(addr);                                  }
void store()     { assert(Dp>=2); uint addr=D[--Dp]; uint n=D[--Dp];
                  assert(addr<Msz); Mset(addr,n);                      }
void cmove()   { assert(Dp>=3); uint sz=D[--Dp],dst=D[--Dp],src=D[--Dp];
           assert(src+sz<Msz); assert(dst+sz<Msz);
           memmove(&M[dst],&M[src],sz);                                }


Код:
void step() {
switch(op) {
            case 0x20: Cfetch(); break;  case 0x21: Cstore(); break;
            case 0x22: fetch(); break;   case 0x23: store(); break;
            #ifdef MODE32
//                   case 0x24: Wfetch(); break;
//                   case 0x25: Wstore(); break;
            #else
                   case 0x24: fetch(); break;
                   case 0x25: store(); break;
            #endif
            case 0x26: cmove(); break;


тут есть команды работы с 16-битными данными, для 32-битного варианта компиляции движка пока код не написан, а для 16-битного эти команды используют тот же код что и обычные @ !

Код:
0x20 0op c@   0x21 0op c!
0x22 0op @   0x23 0op !
0x24 0op w@   0x25 0op w!   

0x26 0op cmove

_________________
http://akps.ssau.ru/forth/


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Вс июн 03, 2007 12:32 
Не в сети

Зарегистрирован: Сб май 06, 2006 18:43
Сообщения: 400
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
целочисленная арифметика

Код:
void add()       { assert(Dp>=2); int n2=D[--Dp],n1=D[--Dp]; D[Dp++]=n1+n2; }
void sub()       { assert(Dp>=2); int n2=D[--Dp],n1=D[--Dp]; D[Dp++]=n1-n2; }
void mul()       { assert(Dp>=2); int n2=D[--Dp],n1=D[--Dp]; D[Dp++]=n1*n2; }
void div()       { assert(Dp>=2); int n2=D[--Dp],n1=D[--Dp]; D[Dp++]=n1/n2; }
void mod()    { assert(Dp>=2); int n2=D[--Dp],n1=D[--Dp]; D[Dp++]=n1%n2; }
void zmin()   { assert(Dp>=2); int n2=D[--Dp],n1=D[--Dp];
                if (n1<n2) D[Dp++]=n1; else D[Dp++]=n2; }
void zmax()   { assert(Dp>=2); int n2=D[--Dp],n1=D[--Dp];
                if (n1<n2) D[Dp++]=n2; else D[Dp++]=n1; }

#ifdef DOS16
void rnd() { assert(Dp>=1); D[Dp-1]=random(D[Dp-1]+1); }
#endif


Код:
void step() {
switch(op) {
            case 0x30: add(); break;     case 0x31: sub(); break;
           case 0x32: mul(); break;     case 0x33: div(); break;
            case 0x34: mod(); break;
            case 0x35: zmin(); break;    case 0x36: zmax(); break;
            #ifdef DOS16
                   case 0x37: rnd(); break;
            #endif


генерацию случайный чисел пока нашел как делать только под DOS

Код:
0x30 0op +   0x31 0op -   0x32 0op *   0x33 0op /
0x34 0op mod   0x35 0op min   0x36 0op max   0x37 0op rnd

_________________
http://akps.ssau.ru/forth/


Последний раз редактировалось forth@km.ru Вс июн 03, 2007 12:39, всего редактировалось 1 раз.

Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Вс июн 03, 2007 12:37 
Не в сети

Зарегистрирован: Сб май 06, 2006 18:43
Сообщения: 400
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
логика и битовые операции

Код:
void eq()        { assert(Dp>=2); int n2=D[--Dp],n1=D[--Dp];
                  if (n1==n2) D[Dp++]=-1; else D[Dp++]=0;                 }
void noteq()     { assert(Dp>=2); int n2=D[--Dp],n1=D[--Dp];
                  if (n1!=n2) D[Dp++]=-1; else D[Dp++]=0;                 }
void less()      { assert(Dp>=2); int n2=D[--Dp],n1=D[--Dp];
                  if (n1<n2) D[Dp++]=-1; else D[Dp++]=0;                  }
void great()     { assert(Dp>=2); int n2=D[--Dp],n1=D[--Dp];
                  if (n1>n2) D[Dp++]=-1; else D[Dp++]=0;                  }
void leq()      { assert(Dp>=2); int n2=D[--Dp],n1=D[--Dp];
                  if (n1<=n2) D[Dp++]=-1; else D[Dp++]=0;                 }
void geq()      { assert(Dp>=2); int n2=D[--Dp],n1=D[--Dp];
                  if (n1>=n2) D[Dp++]=-1; else D[Dp++]=0;                 }

void not()     { assert(Dp>=1); D[Dp-1]=~D[Dp-1]; }
void or()      { assert(Dp>=2); uint n2=D[--Dp],n1=D[--Dp]; D[Dp++]=n1|n2; }
void and()     { assert(Dp>=2); uint n2=D[--Dp],n1=D[--Dp]; D[Dp++]=n1&n2; }
void xor()     { assert(Dp>=2); uint n2=D[--Dp],n1=D[--Dp]; D[Dp++]=n1^n2; }
void lshift()  { assert(Dp>=2); uint n2=D[--Dp],n1=D[--Dp]; D[Dp++]=n1<<n2; }
void rshift()  { assert(Dp>=2); uint n2=D[--Dp],n1=D[--Dp]; D[Dp++]=n1>>n2; }


Код:
void step() {
switch(op) {
            case 0x40: eq(); break;      case 0x41: noteq(); break;
            case 0x42: less(); break;    case 0x43: great(); break;
            case 0x44: leq(); break;     case 0x45: geq(); break;

            case 0x48: not(); break;     case 0x49: or(); break;
            case 0x4A: and(); break;     case 0x4B: xor(); break;
            case 0x4C: lshift(); break;  case 0x4D: rshift(); break;


Код:
0x40 0op =   0x41 0op !=   : <> != ;
0x42 0op <   0x43 0op >
0x44 0op <=   0x45 0op >=

0x48 0op not   0x49 0op or   0x4A 0op and   0x4B 0op xor
0x4C 0op <<   0x4D 0op >>

_________________
http://akps.ssau.ru/forth/


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Вс июн 03, 2007 12:45 
Не в сети

Зарегистрирован: Сб май 06, 2006 18:43
Сообщения: 400
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
консольный ввод/вывод

Код:
void qkey()   { assert(Dp<Dsz); D[Dp++]=-1; }
void key()    { assert(Dp<Dsz); D[Dp++]=getchar(); }
void qemit()  { assert(Dp<Dsz); D[Dp++]=-1; }
void emit()   { assert(Dp>=1);
                if (D[Dp-1]==0x0A) putchar(0x0D); putchar(D[--Dp]); }


Код:
void step() {
switch(op) {
            case 0x70: qkey(); break;    case 0x71: key(); break;
            case 0x72: qemit(); break;   case 0x73: emit(); break;


вообще тут нужна проработка -- давать ли прямой доступ к консоли, работать через stdio/stdout, делать ли какие-то потоки ввода/вывода с созданием/переключением/итп, короче нужна проработка

Код:
\ консольный ввод/вывод (фактически расширение -- может просто не поддерживатся железом)

0x70 0op ?key   0x71 0op key   0x72 0op ?emit   0x73 0op emit

_________________
http://akps.ssau.ru/forth/


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Вс июн 03, 2007 12:53 
Не в сети

Зарегистрирован: Сб май 06, 2006 18:43
Сообщения: 400
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
отладка

Код:
void sdot() { printf("\n[ ");
              for (uint i=0;i<Dp;i++) printf("%i ",D[i]);
              printf("]\n");                                                }
void dump() { assert(Dp>=1);
              uint len=D[--Dp],addr=D[--Dp]; assert(addr+len<Msz);
              printf("\n[ ");
              for (uint i=addr;i<addr+len;i++) printf("%.2X ",M[i]);
              printf("]\n");                                                }
void hdot() { assert(Dp>=1);
              #ifdef MODE16
                     printf("%.4X ",D[--Dp]);
              #else
                     printf("%.8X ",D[--Dp]);
              #endif
                                                                            }
void dot()  { assert(Dp>=1); printf("%i ",D[--Dp]); }


Код:
void step() {
switch(op) {
            case 0x80: sdot(); break;    case 0x81: dump(); break;
            case 0x82: hdot(); break;    case 0x83: dot(); break;


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

Код:
0x80 0op s.   0x81 0op dump   0x82 0op h.   0x83 0op .


еще -- слова типа h. . перенести в консольный ввод/вывод как часто используемые, или оставить в отладке, а консольный вывод чисел реализовать в байт-коде специально

_________________
http://akps.ssau.ru/forth/


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Пн июн 04, 2007 00:26 
Не в сети

Зарегистрирован: Сб май 06, 2006 12:01
Сообщения: 959
Откуда: Украина, Харьков
Благодарил (а): 2 раз.
Поблагодарили: 7 раз.
Я еще раз предложу использовать макросы С для упрощения (и повышения читабельности) исходников... ;)

_________________
With best wishes, in4.


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Пн июн 04, 2007 06:16 
Не в сети
Аватара пользователя

Зарегистрирован: Пт май 05, 2006 06:19
Сообщения: 192
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
еще раз скажу, в истоках форт меня заинтересовал своей простотой и НЕ_СИ_СИНТАКСИСОМ
не испытываю лично не капли восторга от внедрения си подобных конструкций

_________________
SPF


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 39 ]  На страницу Пред.  1, 2, 3  След.

Часовой пояс: UTC + 3 часа [ Летнее время ]


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2


Вы не можете начинать темы
Вы можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
phpBB сборка от FladeX // Русская поддержка phpBB