Важная информация

User Tag List

Страница 5 из 11 ПерваяПервая 123456789 ... ПоследняяПоследняя
Показано с 41 по 50 из 109

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

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

    По умолчанию

    LD DE, 0000 + ADD HL, DE = 10+4 = 14 тактов
    LD A,H + OR L = 5+4 = 9 тактов

    Но если DE загружать вне цикла, то покатит.
    Последний раз редактировалось vinxru; 13.09.2012 в 16:37.

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

    По умолчанию

    LXI 10 тактов. DAD тоже. Итого 20.

    ---------- Post added at 17:37 ---------- Previous post was at 17:36 ----------

    Давай будем разговаривать в мнемониках i8080

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

    По умолчанию

    http://www.emuverse.ru/wiki/Intel_80...B0%D0%BD%D0%B4

    DAD = 4 такта

    ---------- Post added at 15:39 ---------- Previous post was at 15:38 ----------

    А в Intel_8080_ASM_Lang_Manual.pdf написано 10

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

    По умолчанию

    Цитата Сообщение от vinxru Посмотреть сообщение
    Опечатка. Даташит не врёт

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

    По умолчанию

    Я тут просматривал код:
    Код:
      ; for(x=0; x<64; x+=16) {
      xor a
      ld (main_x), a
    l10:
      ld d, 64
      ld a, (main_x)
      call l_uchar
      or a
      jp z, l11
      jp l12
    l13:
      ld a, (main_x)
      add 16
      ld (main_x), a
      jp l10
    l12:
    
    
      ; }
      jp l13
    l11:
    И подумал - а не стоит ли переменные засовывать прямо в код, для циклов? Выделенную строчку заменить на две:
    main_x_var:
    ld a,0
    нолик, соответственно, место где хранится переменная, она же теперь часть кода. Соответственно, обращаться к переменной теперь не ld a, (main_x), а ld a, (main_x_var+1). Код на байт короче, байт экономится на глобальной переменной, 6 тактов на каждой итерации цикла. Правда 2 минуса - нужно следить за обращением к x, он теперь на новом месте, и такой код нельзя зашить в ROM.
    Последний раз редактировалось predatoralpha; 14.09.2012 в 00:42.

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

    По умолчанию

    Хм, сделаю и такой режим Но когда переменные лежат одним блоком, легко реализовать рекурсию. Просто этот блок переменных копировать в стек.

    Выхожу на финишную прямую с кодогенератором. Сделал операции < > <= >= == != для uchar. Сделал #define #undef (как полагается с параметрами).

    Код:
    print_return ds 0
    print_x ds 1
    print_y ds 1
    print_text ds 2
    print_dest ds 2
    print:
      push bc
      ld (print_text), hl
      ; 10 dest = (uchar*)(0xE1D5 + x + y*78);
      ld hl, (print_x)
      ld h, 0
      ld de, 57813
      add hl, de
      push hl
      ld d, 78
      ld a, (print_y)
      call mul_uchar
      pop de
      add hl, de
      ld bc, hl
      ; 11 while(*text) { *dest = *text; dest++; text++; }
    l2:
      ld hl, (print_text)
      ld a, (hl)
      or a
      jp z, l3
      ; 11 *dest = *text; dest++; text++; }
      ld hl, (print_text)
      ld a, (hl)
      ld (bc), a
      ; 11 dest++; text++; }
      inc bc
      ; 11 text++; }
      ld hl, (print_text)
      inc hl
      ld (print_text), hl
      jp l2
    l3:
    l1:
      pop bc
      ret
    ;----------------------------------
    clrscr_return ds 0
    clrscr_dest ds 2
    clrscr_c ds 2
    clrscr:
      push bc
      ; 17 dest = (uchar*)0xE1D0-1;
      ld hl, 57807
      ld (clrscr_dest), hl
      ; 18 c = 78*25;
      ld bc, 1950
      ; 19 do *++dest = 0; while(c--);
    l5:
      ; 19 *++dest = 0; while(c--);
      ld hl, (clrscr_dest)
      inc hl
      ld (clrscr_dest), hl
      xor a
      ld hl, (clrscr_dest)
      ld (hl), a
      dec bc
      ld a, b
      or c
      jp nz, l5
    l4:
      pop bc
      ret
    ;----------------------------------
    get:
      ; 23 return 23;
      ld hl, 23
      jp l6
    l6:
      ret
    ;----------------------------------
    atoi_return ds 0
    atoi_str1 ds 2
    atoi_a ds 2
    atoi_str ds 2
    atoi_c ds 1
    atoi:
      push bc
      ld (atoi_a), hl
      ; 31 str = str1;
      ld hl, (atoi_str1)
      ld bc, hl
      ; 32 do {
    l8:
      ; 33 c = ((uchar)a & 15) + 48;
      ld a, (atoi_a)
      and 15
      add 48
      ld (atoi_c), a
      ; 34 if('9' < c) c += 7;
      ld a, (atoi_c)
      cp 57
      jp c, l10
      ; 34 c += 7;
      ld a, (atoi_c)
      add 7
      ld (atoi_c), a
    l10:
      ; 35 *str = c; str++;
      ld a, (atoi_c)
      ld (bc), a
      ; 35 str++;
      inc bc
      ; 36 a = a >> 4;
      ld de, 4
      ld hl, (atoi_a)
      call shr_ushort
      ld (atoi_a), hl
      ld hl, (atoi_a)
      ld a, l
      or h
      jp nz, l8
      ; 38 *str = 0;
      xor a
      ld (bc), a
    l7:
      pop bc
      ret
    ;----------------------------------
    main_return ds 0
    main_i ds 1
    main_x ds 1
    main_buf ds 32
    main:
      push bc
      ; 47 clrscr();
      call clrscr
      ; 48 print(0, 0, "HELLO");
      xor a
      ld (print_x), a
      xor a
      ld (print_y), a
      ld hl, string0
      call print
      ; 49 atoi(buf, 0x12AB);
      ld hl, main_buf
      ld (atoi_str1), hl
      ld hl, 4779
      call atoi
      ; 51 print(1, 1, buf);
      ld a, 1
      ld (print_x), a
      ld a, 1
      ld (print_y), a
      ld hl, main_buf
      call print
      ; 53 i=5;
      ld b, 5
      ; 55 for(x=0; x<64; x+=XYZ(12)) {
      ld c, 0
    l12:
      ld a, c
      cp 64
      jp nc, l13
    l12:
      ; 56 print(x, i, "12345678.123");
      ld a, c
      ld (print_x), a
      ld a, b
      ld (print_y), a
      ld hl, string1
      call print
      ld a, c
      add 14
      ld c, a
      jp l12
    l13:
      ; 59 while(1) {
    l15:
      ; 60 if(getch() == '1') clrscr();
      call getch
      cp 49
      jp nz, l18
      ; 60 clrscr();
      call clrscr
    l18:
      jp l15
    l16:
    l11:
      pop bc
      ret
    В этом коде еще убрать дублирующиеся присваивания переменных (ld a, 1 ld (print_x), a ld a, 1) или (ld (atoi_a), hl, ld hl, (atoi_a)) и т.д. Эта уборка будет отключатся словом volatile. Объединить XOR A и LD (HL), A, например (xor a ld hl, (clrscr_dest) ld (hl), a). И убрать лишние переходы, например jp $+3 или jp на другой jp.

    1888 строк 54 Кб.

    ---------- Post added at 03:23 ---------- Previous post was at 02:47 ----------

    Мне написали, что есть компиляторы Си для 8080.

    https://github.com/begoon/smallc-scc3, https://github.com/begoon/smallc-85

    и работают они так

    Код:
    main() {
    static char a;
    for (a = '\0'; a < '\10'; ++a) {
    a = a + '\1';
    }
    }
    
    (специально использовал char везде) генерит адъ типа:
    
    ;main() {
    main:
    ; static char a;
    dseg
    ?2: ds 1
    cseg
    ; for (a = '\0'; a < '\10'; ++a) {
    lxi h,?2
    push h
    lxi h,0
    pop d
    call ?pchar
    ?3:
    lxi h,?2
    call ?gchar
    push h
    lxi h,12592
    pop d
    call ?lt
    mov a,h
    ora l
    jnz ?5
    jmp ?6
    ?4:
    lxi h,?2
    push h
    call ?gchar
    inx h
    pop d
    call ?pchar
    jmp ?3
    ?5:
    ; a = a + '\1';
    lxi h,?2
    push h
    lxi h,?2
    call ?gchar
    push h
    lxi h,49
    pop d
    dad d
    pop d
    call ?pchar
    ; }
    jmp ?4
    ?6:
    ;}
    ?1:
    ret
    
    мой
    
    main:
      push bc
      ; 3 for (a = 0; a < 10; ++a) {
      ld b, 0
    l1:
      ld a, b
      cp 10
      jp nc, l2
    l1:
      ; 4 a = a + 1;
      ld a, b
      inc a
      ld b, a
      inc b
      jp l1
    l2:
    l0:
      pop bc
      ret
    Последний раз редактировалось vinxru; 14.09.2012 в 03:15.

  7. #46
    С любовью к вам, Yandex.Direct
    Размещение рекламы на форуме способствует его дальнейшему развитию

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

    По умолчанию

    Цитата Сообщение от vinxru Посмотреть сообщение
    Хм, сделаю и такой режим Но когда переменные лежат одним блоком, легко реализовать рекурсию. Просто этот блок переменных копировать в стек.
    Ну далеко не всегда нужно все переменные копировать в стек. В идеале нужно вести время жизни переменных. Часть переменных уже не используется, часть ещё не присвоены, часть будут безусловно проинициализированы после вызова, и текущее значение не нужно.

    А это зачем?
    ld hl, (clrscr_dest)
    ld (hl), a

    Регистр а можно прямо поместить по нужному адресу.

    Кстати, 0xE1D5 + x можно ещё оптимальнее
    Вместо
    ld hl, (print_x)
    ld h, 0
    ld de, 57813 // 0xE1D5
    add hl, de

    Сделать
    ld hl, (print_x)
    ld de, 0x0СD5 // d=E1-D5=0C
    ld h, е // На байт короче, на 3 такта быстрее
    add hl, de


    А вот здесь у тебя неверный код, вроде
    while(c--);
    dec bc
    ld a, b
    or c
    jp nz, l5

    У тебя код не постдекрементный, а преддекрементный. Т.е. для случая while(--c), а не while(c--).

  9. #48
    Moderator
    Регистрация
    14.08.2006
    Адрес
    Владимир
    Сообщений
    4,577
    Спасибо Благодарностей отдано 
    61
    Спасибо Благодарностей получено 
    106
    Поблагодарили
    92 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Переменные на стеке нужны для реентабельности процедур. Это не только рекурсия, но и второе в хождение в ту же процедуру из обработчика перерывания. Соответственно, в случае работы системы с прерываниями, копировать глобальные переменные на стек бессмысленно - остается вероятность что по прерыванию будет повторное вхождение пока переменные еще не скопированы. Ну и если будет такое копирование, всякий выигрыш теряется (что про времени выполнения, что по размеру кода). Тогда уж сразу надо делать на стеке.
    Последний раз редактировалось Error404; 14.09.2012 в 14:24.
    Лучше сделать и жалеть, чем не сделать и жалеть.

    Некоторые из моих поделок тут: https://github.com/serge-404

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

    По умолчанию

    Цитата Сообщение от Error404 Посмотреть сообщение
    Переменные на стеке нужны для реентабельности процедур. Это не только рекурсия, но и второе в хождение в ту же процедуру из обработчика перерывания. Соответственно, в случае работы системы с прерываниями, копировать глобальные переменные на стек бессмысленно - остается вероятность что по прерыванию будет повторное вхождение пока переменные еще не скопированы. Ну и всякий выигрыш теряется (что про времени выполнения, что по размеру кода) если будет такое копирование: тогда уж сразу надо делать на стеке.
    Насчёт реентабельности по прерываниям - да, абсолютно верно, такие процедуры нереентабельные. А вот с "Ну и всякий выигрыш теряется (что про времени выполнения, что по размеру кода)" я не согласен. Для 8080 (не Z80) операции со стеком весьма и весьма мудоёмкие, сжирающие как минимум одну из трёх регистровых пар (HL), которая весьма незаменима, а это постоянные прологи из двух-пяти команд для каждого обращения к стеку. Выигрыш весьма существенный. Особенно в тех случаях, когда возможен анализ кода, есть ли возможность рекурсии при вызове некой функции.
    -
    Проблема нереентабельности по прерываниям, как по мне, несущественная. Обработчик обычно пишется на ассемблере, если какие-то сишные функции и будут вызываться - то обычно это не те, что выполняются вне прерывания. Этот факт нужно отразить в документации, и принять его "как есть".
    -
    Более серьёзная проблема, как по мне - это передача ссылки на локальную переменную в некую функцию. Если создаются копии локальных переменных в стеке, то ссылка на локальную переменную "повиснет". А если ещё добавить, что вызываемая функция эту ссылку может сохранить в глобальной переменной, и другая вызываемая функция (из базовой функции) эту ссылку может оттуда поднять... Тут весьма сложный момент. И врядли он будет сделан в соответствии со стандартами языка. Я не хочу сейчас грузить vinxru этой проблемой. Он и так молодец.
    Последний раз редактировалось predatoralpha; 14.09.2012 в 14:58.

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

    По умолчанию

    Цитата Сообщение от predatoralpha Посмотреть сообщение
    ld hl, (clrscr_dest)
    ld (hl), a
    В ячейке clrscr_dest хранится адрес, который предыдущей строкой увеличивается.

    Нет на 8080 команды ld ((clrscr_dest)), A

    А вот на PDP-11 есть.

    ---------- Post added at 14:31 ---------- Previous post was at 14:30 ----------

    Цитата Сообщение от predatoralpha Посмотреть сообщение
    А вот здесь у тебя неверный код, вроде
    while(c--);
    dec bc
    ld a, b
    or c
    jp nz, l5
    У тебя код не постдекрементный, а преддекрементный. Т.е. для случая while(--c), а не while(c--).
    Да, я пока одну версию операторов написал. Сегодня поправлю, а то забуду.

    ---------- Post added at 14:34 ---------- Previous post was at 14:31 ----------

    Цитата Сообщение от Error404 Посмотреть сообщение
    Ну и если будет такое копирование, всякий выигрыш теряется (что про времени выполнения, что по размеру кода). Тогда уж сразу надо делать на стеке.
    Чисто арифметически выигрыш есть. Копируем мы переменную один раз на входе, один на выходе. Причем, копирование всех переменных можно делать за один присест.

    А обращаться к переменной мы будем много раз, может быть что 1000 раз.

    ---------- Post added at 14:35 ---------- Previous post was at 14:34 ----------

    Цитата Сообщение от predatoralpha Посмотреть сообщение
    Проблема нереентабельности по прерываниям, как по мне, несущественная. Обработчик обычно пишется на ассемблере, если какие-то сишные функции и будут вызываться - то обычно это не те, что выполняются вне прерывания. Этот факт нужно отразить в документации, и принять его "как есть".
    Можно продублировать функцию вызываемую из прерывания и из основного кода.

    ---------- Post added at 14:37 ---------- Previous post was at 14:35 ----------

    Цитата Сообщение от predatoralpha Посмотреть сообщение
    Более серьёзная проблема, как по мне - это передача ссылки на локальную переменную в некую функцию. Если создаются копии локальных переменных в стеке, то ссылка на локальную переменную "повиснет". А если ещё добавить, что вызываемая функция эту ссылку может сохранить в глобальной переменной, и другая вызываемая функция (из базовой функции) эту ссылку может оттуда поднять...
    Это компромисс между
    1) Программой, которая умеет рекурсию.
    2) И программой, которая работает в 3 раза быстрее.

Страница 5 из 11 ПерваяПервая 123456789 ... ПоследняяПоследняя

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

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

Эту тему просматривают: 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

Ваши права

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