User Tag List

Страница 3 из 12 ПерваяПервая 1234567 ... ПоследняяПоследняя
Показано с 21 по 30 из 111

Тема: Кросскомпилятор Си под 8080

  1. #21
    R.I.P.
    Регистрация
    16.09.2009
    Адрес
    г. Харьков
    Сообщений
    1,466
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    4
    Поблагодарили
    4 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    может нафиг эти C-Strings
    постоянное место для граблей

  2. #22
    Banned
    Регистрация
    01.12.2010
    Адрес
    г. Санкт-Петербург
    Сообщений
    1,657
    Записей в дневнике
    21
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    2
    Поблагодарили
    1 сообщение
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Получилось 150 строк кода, для программы преобразующей синтаксис Си и байткод. И там почти все закончено. И 300 строк для байткода. Причем реализовано лишь 5% всех функций байткода.

    Код:
    ...
    
    void bindVar(CType& type) {
      // Чтение монооператора, выполнять будет потом
      vector<MonoOperator> mo;
      while(true) {
        if(p.ifToken("*")) { mo.push_back(moDeaddr); continue; }
        if(p.ifToken("&")) { mo.push_back(moAddr); continue; }
        if(p.ifToken("!")) { mo.push_back(moNot); continue; }
        if(p.ifToken("-")) { mo.push_back(moNeg); continue; }
        break;
      }
    
      bindVar_2(p, type);
    
      while(true) {
        if(p.ifToken("[")) {
          CType type1;
          readVar(p, -1, type1);
          p.needToken("]");
          if(type1.addr!=0) raise("[]");
          asm_index(type);
          continue;
        }
        if(p.ifToken("++")) { asm_callMonoOperator(moPostInc, type); continue; }
        if(p.ifToken("--")) { asm_callMonoOperator(moPostDec, type); continue; }
        break;
      }
    
      // Вычисление моно операторов
      for(int i=0; i<mo.size(); i++)
        asm_callMonoOperator(mo[i], type);
    }
    
    const char_t* operators [] = { "++", "--", "/", "%", "*", "+", "-", "<<", ">>", "<", ">", "<=", ">=", "==", "!=", "&",  "^",  "|", "&&",  "||", "?", "=", "+=", "-=", "*=", "/=", "%=", ">>=", "<<=", "&=", "^=", "|=", 0 };
    int           operatorsP[] = { 13,   13,   12,  12,  12,  11,  11,  10,   10,   9,   9,   9,     9,    8,   8,    7,    6,    5,   3,     2,    1,   0,   0,    0,    0,    0,    0,    0,     0,     0,    0,    0       };
    Operator      operatorsI[] = { oInc, oDec, oDiv,oMod,oMul,oAdd,oSub,oShl, oShr, oL,  oG,  oLE,  oGE,  oE,   oNE,  oAnd, oXor, oOr, oLAnd, oLOr, oIf, oSet,oSAdd,oSSub,oSMul,oSDiv,oSMod,oSShl, oSShr, oSAnd,oSXor,oXOr    };
    
    void readVar(int level, CType& type) {
      // Чтение аргумента
      bindVar(type);
    
      // Чтение оператора
      while(true) {    
        int l=0;
        Operator o = findOperator(p, level, l);
        if(o == oNone) return;
    
        //! Оптимизировать проверку условий.
        //! Команда ? :
    
        // Чтение второго аргумента
        CType b_type;
        readVar(p, l, b_type);
    
        // Выполнение опертора
        asm_callOperator(o, type, b_type);
      }
    }
    
    void readCommand() {
      if(p.ifToken(";")) return;
    
      if(p.ifToken("while")) {
        p.needToken("(");
        CType type;
        readVar(p, -1, type);
        int label1 = labelesCnt++;
        int label2 = labelesCnt++;
        asm_label(label1);
        asm_jz(label2, type);
        p.needToken(")"); 
        readCommand(p);
        asm_jmp(label1);
        asm_label(label2);
        return;
      }
    
      if(p.ifToken("if")) {
        p.needToken("(");
        CType type;
        readVar(p, -1, type);
        p.needToken(")"); 
        int label1 = labelesCnt++;
        asm_jz(label1, type);
        readCommand(p);
        if(p.ifToken("else")) {
          int label2 = labelesCnt++;
          asm_jmp(label2);
          asm_label(label1);
          readCommand(p);
          asm_label(label2);
        } else {
          asm_label(label1);
        }
        return;
      }
      ...
    }


    ---------- Post added at 19:46 ---------- Previous post was at 19:43 ----------

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

    Код:
    void pushHL(int l, bool de=false) {
      Stack& bs = stack[stack.size()-1-l];
      switch(bs.place) {
        case pConst: code.str(de ? "  ld de" : "  ld hl").str(", ").i2s(bs.value).str("\r\n"); break;
        case pVar:   code.str("  ld hl, (").str(bs.name).str(")\r\n"); 
                     if(de) code.str("  ex de, hl\r\n");
                     break;
        case pVar8:  code.str("  ld hl, (").str(bs.name).str(")\r\n"); 
                     code.str("  ld h, 0\r\n"); 
                     if(de) code.str("  ex de, hl\r\n");
                     break;
        case pRef:   code.str("  ld hl, (").str(bs.name).str(")\r\n"); 
                     if(!de) {
                       code.str("  ld a, (hl)\r\n"); 
                       code.str("  inc hl\r\n"); 
                       code.str("  ld h, (hl)\r\n"); 
                       code.str("  ld l, a\r\n"); 
                     } else {
                       code.str("  ld e, (hl)\r\n"); 
                       code.str("  inc hl\r\n"); 
                       code.str("  ld d, (hl)\r\n"); 
                     }
                     break;
        case pConstRef: code.str("  ld hl, (").i2s(bs.value).str(")\r\n"); 
                     if(de) code.str("  ex de, hl\r\n");
                     break;
        default: raise("3");
      }
    }
    
    void asm_callOperator(Operator o, CType& a, CType b) {    
      Stack& as = stack[stack.size()-2];
      Stack& bs = stack[stack.size()-1];
    
      // Преобразование константы USHORT в UCHAR
      if(a.baseType==cbtUChar && b.baseType==cbtUShort && bs.place==pConst) {
        if(bs.value>=0 && bs.value<=0xFF) b = cbtUChar;
      }
    
      if(a.baseType!=b.baseType || a.addr !=b.addr) 
        raise("asm_callOperator type");
    
      if(o==oSet) {
        if(a.baseType==cbtUChar && a.addr==0) {
          pushA(0);
          switch(as.place) {
            case pConst:    raise("Нельзя изменить константу"); break;
            case pRef:      code.str("  ld hl, (").str(as.name).str(")\r\n");
                            code.str("  ld (hl), a\r\n\r\n");  break;
            case pVar:      code.str("  ld (").str(as.name).str("), a\r\n\r\n"); break;
            case pConstRef: code.str("  ld (").i2s(as.value).str("), a\r\n\r\n"); break;
            default: raise("2");
          }
          stack.pop_back();
          return;
        }
        if((a.baseType==cbtUShort || a.baseType==cbtShort) || a.addr>0) {
          pushHL(0);
          switch(as.place) {
            case pConst:    raise("Нельзя изменить константу"); break;
            case pRef:      code.str("  ex hl, de\r\n");
                            code.str("  ld hl, (").str(as.name).str(")\r\n");
                            code.str("  ld (hl), e\r\n");
                            code.str("  inc hl\r\n");
                            code.str("  ld (hl), d\r\n\r\n");  break;
            case pVar:      code.str("  ld (").str(as.name).str("), hl\r\n\r\n"); break;
            case pConstRef: code.str("  ld (").i2s(as.value).str("), hl\r\n\r\n"); break;
            default: raise("4");
          }
          stack.pop_back();
          return;
        }
        raise("xxx");
        return;
      }
    Последний раз редактировалось vinxru; 11.09.2012 в 21:17.

  3. #23
    Banned
    Регистрация
    01.12.2010
    Адрес
    г. Санкт-Петербург
    Сообщений
    1,657
    Записей в дневнике
    21
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    2
    Поблагодарили
    1 сообщение
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Вчера скомпилировал первые программы. Мне этого функционала пока хватит для написания меню. А по мелочи добавлю.

    Ключевые слова break, continue, return, switch, default, do {} while, union, typedef, extern, sizeof не реализованы.

    Описание внешних функций (прототипы), переменных не реализованы. Например: int myFunction(int); extern int a;

    Арифметика реализована только для типов uchar, ushort. Только операции +, -, ++, --, +=, -=, |=, &=, ^=, *, /, =, |, &, ^, <. Например сдвигов пока нет. Операции с типами ulong, long производить пока нельзя.

    Инициализации статических переменных нет Например: char data[] = { 0x10, 0x20 }; FileInfo files[] = { { "abc", 1 }, { "def", 2 } };

    Типы данных real, float, double, const, static, register, volatile, auto не реализованы. Слово register будет заставлять размещать переменную в регистре BC (или B или C).

    Препроцессор не реализован, хотя там 5 минут работы. Например: #include, #define, #ifdef, #ifndef, #endif

    Вставки ассемблера не реализованы.

    Грамотный учет временных переменных не реализован. Резервирует больше памяти, чем нужно. Вообще переделаю на push hl, pop hl

    Контроля рекурсии нет и необходимый размер стека не определяется. Рекурсия кстати будет. При рекурсивном вызове функции, все переменные используемые предыдущим вызовом функции будут копироваться в стек, а новая функция будет работать с фиксированной памятью. Не идеальный способ, но относительно быстрый. Будут проблемы при использовании указателей на локальные переменные.

    Функции сравнения не оптимизированы. Сейчас первым этапом сравнения вычисляется значение True, False, а уже потом оно анализируется функцей перехода.

    Сравнение

    ld a, (var1)
    ld hl, (var2)
    cp (hl)
    sbc a

    Переход

    or a
    jp z, label
    Последний раз редактировалось vinxru; 17.09.2012 в 02:03.

  4. #24
    Member
    Регистрация
    08.01.2012
    Адрес
    г.Винница, Украина
    Сообщений
    65
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    0
    Поблагодарили
    0 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    А как обстоят дела с макросами и #include ??

    Кстати, do {} while может быть и без фигурных скобок.

    do ;
    while (i--);
    корректный пример организации задержки.
    Последний раз редактировалось predatoralpha; 12.09.2012 в 11:54.

  5. #25
    Banned
    Регистрация
    01.12.2010
    Адрес
    г. Санкт-Петербург
    Сообщений
    1,657
    Записей в дневнике
    21
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    2
    Поблагодарили
    1 сообщение
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Вообще, байткод получившегося Си очень сильно напоминает PDP11. (Что не удивительно). Все адресации переменных копируют адресацию PDP11.

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

    Для всех двухадресных 16 битных команд регистр HL используется для хранения основного значения, DE для второго. Команды "EX HL, DE", "LD HL, IMM", "LD HL, (ADDR)", "ADD HL, DE", "LD (ADDR), HL" используются постоянно. Традиционно: XCHG, LHLD, LXI H, DAD D, SHLD


    addr = (y*78 + 0xA000 + x - offset ) | 1234h;

    ; y*78
    LD A, (Y)
    LD D, 78
    CALL MUL_UCHAR8 ; Вход A,D. Выход HL

    ; +0xA000
    LD DE, 0A000h
    ADD HL, DE

    ; +x
    EX HL, DE
    LD HL, (x) ; 8 бит
    LD H, 0
    ADD HL, DE

    ; -offset
    EX HL, DE
    LD HL, (offset)
    LD A, E
    SUB L
    LD L, A
    LD A, D
    SBC H
    LD H, A

    ; | 1234h
    LD A, L
    OR 34h
    LD L, A
    LD A, H
    OR 12h
    LD H, A

    ; addr=
    LD (addr), HL

    Но все таки не понятно, почему команды

    LD BC, IMM16
    LD HL, IMM16

    есть, а

    LD DE, нет
    Последний раз редактировалось vinxru; 13.09.2012 в 13:12.

  6. #26
    Guru
    Регистрация
    24.01.2008
    Адрес
    Уфа
    Сообщений
    3,852
    Спасибо Благодарностей отдано 
    84
    Спасибо Благодарностей получено 
    235
    Поблагодарили
    171 сообщений
    Mentioned
    9 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от vinxru Посмотреть сообщение
    LD BC, IMM16
    LD HL, IMM16

    есть, а

    LD DE, нет
    Как это нет?

  7. #27
    Banned
    Регистрация
    01.12.2010
    Адрес
    г. Санкт-Петербург
    Сообщений
    1,657
    Записей в дневнике
    21
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    2
    Поблагодарили
    1 сообщение
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Ой, есть

    ---------- Post added at 11:18 ---------- Previous post was at 11:15 ----------

    Цитата Сообщение от predatoralpha Посмотреть сообщение
    А как обстоят дела с макросами и #include ??
    Парсер их поддерживает, надо только пару строк написать.

    ---------- Post added at 11:23 ---------- Previous post was at 11:18 ----------

    Цитата Сообщение от predatoralpha Посмотреть сообщение
    do ;
    while (i--);
    корректный пример организации задержки.
    Да, у меня там DO <команда> WHILE(<вражение>)

    Можно так писать: do a++, b++, c++; while(c<10);

    Вчера во время отладки, перебирая все варианты, написал:

    while(a==1) {
    a=2;
    } while(a==2);

    И долго пялился.

  8. #28
    Member
    Регистрация
    08.01.2012
    Адрес
    г.Винница, Украина
    Сообщений
    65
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    0
    Поблагодарили
    0 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Но все таки не понятно, почему команды

    LD BC, IMM16
    LD HL, IMM16

    есть, а

    LD DE, нет
    А точно нет? В Z80 всем этим командам соответствует опкод
    00 dd0 001
    Где dd для BC=00; DE=01; HL=10; SP=11

    Может в 8080 неверно декодируется команда, когда младший бит dd==1, потому команды так и не появились..


    ПС. Вопрос снят.....

  9. #29
    Banned
    Регистрация
    01.12.2010
    Адрес
    г. Санкт-Петербург
    Сообщений
    1,657
    Записей в дневнике
    21
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    2
    Поблагодарили
    1 сообщение
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Ступил, я вчера думал про команду

    LD DE, (ADDR)

    Вот в этом куске не нужна была бы команда

    EX HL, DE
    LD HL, (offset)
    LD A, E
    SUB L
    LD L, A
    LD A, D
    SBC H
    LD H, A


    Аналогично

    EX HL, DE
    LD HL, (offset)
    ADD HL, DE

    ---

    Традиционно:

    XCHG
    LHLD offset
    MOV A, E
    SUB L
    MOV L, A
    MOV A, D
    SBB H
    MOV H, A

    Аналогично

    XCHG
    LHLD offset
    DAD D

    ---------- Post added at 11:48 ---------- Previous post was at 11:28 ----------

    По сравнению с PDP11 топорно очень

    *a += *b;

    LD HL, (B)
    LD E, (HL)
    INC HL
    LD D, (HL)

    LD HL, (A)
    LD A, (HL)
    INC HL
    LD H, (HL)
    LD L, A

    ADD HL, DE

    EX HL, DE
    LD HL, (A)
    LD (HL), E
    INC HL
    LD (HL), D

    (Можно использовать команды 8-битной арифметики сократить программу на пару строк, но не суть).

    или на PDP11

    ADD @(A), @(B)
    Последний раз редактировалось vinxru; 13.09.2012 в 13:16.

  10. #30
    Member
    Регистрация
    08.01.2012
    Адрес
    г.Винница, Украина
    Сообщений
    65
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    0
    Поблагодарили
    0 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от vinxru Посмотреть сообщение
    Вот в этом куске не нужна была бы команда

    EX HL, DE
    LD HL, (offset)
    LD A, E
    SUB L
    LD L, A
    LD A, D
    SBC H
    LD H, A


    Аналогично

    EX HL, DE
    LD HL, (offset)
    ADD HL, DE
    Тут разве что интеллектуально делать первым не HL, а DE. И команды сложения производить с ним, накапливая в нём результат. Тогда можно обойтись без обмена.
    ПС. Хотя нет, арифметика работает только с HL. Блин, уже основательно подзабыл ассемблер Z80...

    Цитата Сообщение от vinxru Посмотреть сообщение
    Вот в этом куске не нужна была бы команда

    [COLOR="Red"]или на PDP11
    ADD @(A), @(B)
    Да, удобная вещь. Я работал на DSP, там есть команды индексной загрузки с пост- и пред- инкрементом/декрементом, очень быстро работает перебор.
    Последний раз редактировалось predatoralpha; 12.09.2012 в 13:37.

Страница 3 из 12 ПерваяПервая 1234567 ... ПоследняяПоследняя

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Похожие темы

  1. Ассемблер 8080
    от Kakos_nonos в разделе Утилиты
    Ответов: 0
    Последнее: 21.09.2011, 23:35
  2. Продам пару платок с процами 8080
    от RedLine в разделе Барахолка (архив)
    Ответов: 15
    Последнее: 23.12.2010, 18:39
  3. схема АОН на 8080/z80
    от sergey2b в разделе Разный софт
    Ответов: 7
    Последнее: 07.02.2010, 22:43
  4. An 8080/Z80 C Compiler
    от breeze в разделе Программирование
    Ответов: 1
    Последнее: 18.08.2005, 06:54

Ваши права

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