Просмотр полной версии : Осваиваем Hi-Tech C v3.09 для CP/M
Oleg N. Cher
13.01.2017, 05:05
Цель-минимум: собрать рабочий Hello World для Спектрума. Эмулятор CP/M берём здесь (http://www.vector.co.jp/soft/win95/util/se378130.html).
Пока столкнулся с тем, что не работает #asm / #endasm
Такой исходник:
void main (void) {
#asm
ld a,10
#endasm
}даёт такой выхлоп:
H:\Archive\Projects\XDev\ZXDevHC\Bin\CPM>..\cpm C -O -M -S Hello.c
HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
HELLO.C: main()
5: EOF in #asm
Поскольку явного EOF'а in #asm не наблюдается, пробую менять в исходнике код окончания строк с LF (UNIX) на CR (вроде в CP/M так). Тогда компилятор вообще зависает.
Если убрать секцию #asm/#endasm, пустой void main (void) {} собирается в HELLO.COM для CP/M размером 256 байт. Как сгенерить бинарь для ZX - пока непонятно. Возможно, придётся генерировать ассемблерный листинг и ассемблировать отдельно.
А вот что пишет один MSX'ер на форуме по MSX (https://www.msx.org/forum/development/msx-development/c-cross-compiler-z80):
I've used Hi-Tech (free (as in beer), CP/M version) quite a bit. It's OK, but not great.
Также высокохвалёный Sayman'ом хайтех 3.09 не понимает комментов вида //
как я уже говорил, у каждого компилятора есть свои гус. Для хайтеха запись дериктив асм не сначала строки приведёт к ошибке. попробуй сделать #asm и #endasm сначала строки, а не с середины.
Пока столкнулся с тем, что не работает #asm / #endasm
По-моему, это, вообще, не работает. Сталкивался с этим.
Асмовыми вставками не пользуюсь - пишу в отдельных модулях всё, а потом собираю в либу.
во1х, работает. во2х, оптимизатор съедает часть вашего кода на асме, если будете прогонять исходник через него.
Oleg N. Cher
13.01.2017, 11:17
По-моему, это, вообще, не работает. Сталкивался с этим.Sayman прав - если # в начале строки, то работает, даже так можно:
void main (void) {
# asm
ld a,10
# endasm
}На форумах упоминается ещё такой способ для хайтеха: #asm("NOP");
Но не работает:
HELLO.C: main()
2: #asm("NOP");
^ illegal '#' directive
Как получить бинарь вместо HELLO.COM для CP/M?
Вроде упоминалось, что эта версия компилера выдаёт бинарь, всегда кратный 128 байтам. Неприятно, но терпеть можно. Но как его получить?
Также напомните, как вызвать оптимизатор. Его вызывает сам C.COM или дёргаем отдельно?
Можно асмовый код собирать в библиотеки, чтобы его не переиначивал оптимизатор. Кто-нибудь уже создавал и использовал библиотеки с LIBR.COM ? Поддерживается ли хоть какая-то смартлинковка?
Можно ли исходники держать отдельно от файлов компилятора? Директорий в CP/M нет, может можно на другом диске?
Вроде упоминалось, что эта версия компилера выдаёт бинарь, всегда кратный 128 байтам
Так в CP/M все файлы кратны 128 байтам. Это особенность файловой системы.
Smalovsky
13.01.2017, 23:02
Я ,дык, незнаю что делать... Я провёл расследование в теме - программирование в Bascom. Не знаю, можно ли вообще пользоваться си? Хочу услышать ваше мнение. Накрайняк, перепишу код головоломки на бейсике( она у меня простая).
Oleg N. Cher
13.01.2017, 23:32
Пользоваться Си можно. Проверено. Мин нет Местами мины есть. Но кому щас легко.
Зачем переписывать туда-сюда? Уже пиши на чём начал.
Ну и, наконец, только Оберон спасёт отца беларуской демократии! ;-)
Как получить бинарь вместо HELLO.COM для CP/M?
Вот, скрипт на лучшем в мире языке программирования. Почти интуитивно понятный.
Соль в этой строке:
cpm -h link.com -Z -Ptext=5D59H -C5D59H -O"||binfpathname||" STD48.OBJ std48.lib
5D59 - адрес компиляции.
Oleg N. Cher
14.01.2017, 07:07
Насколько я понимаю, -C5D59H это точка входа и стартовый адрес машкода. Что задаёт -Ptext=5D59H ? Можно ли задать адрес для размещения данных? (в SDCC можно) Или данные размещаются всегда строго после кода?
Oleg N. Cher, как говорится, RTFM. 59414
Насколько я понимаю, -C5D59H это точка входа и стартовый адрес машкода.
Как бы намекает: :)
5D59 - адрес компиляции.
Данные, вроде можно. Но мне это не было нужно, потому не знаю, как юзать.
Oleg N. Cher
18.01.2017, 21:30
Итак о моих мытарствах. Наконец-то получил более или менее приемлемый результат. Мой Hello.c
void main (void) {
# asm
ld a,'H'
rst 16
ld a,'E'
rst 16
ld a,'L'
rst 16
ld a,'L'
rst 16
ld a,'O'
rst 16
# endasm
}
@SET MainMod=Hello
@SET CodeAdr=25000
@CD CPM
@..\cpm -h c.com -C %MainMod%.c
@IF errorlevel 1 PAUSE
@..\cpm -h link.com -Z -Ptext=%CodeAdr% -C%CodeAdr% %MainMod%.OBJ libc.lib
@IF errorlevel 1 PAUSE
@CD ..
@stripbin.exe CPM\L.bin
@bin2tap.exe -c 24999 -a %CodeAdr% -r %CodeAdr% -b -o %MainMod%.tap CPM\L.bin
@PAUSEПопытка добавить ключик -O при компиляции приводит к нерабочему сломанному коду. Это конечно фича.
Ключик -O"Hello.bin" для линкера не работает, довольствуюсь именем по умолчанию - L.bin
Нагенерил это. Выглядит не очень, какие-то непонятные пляски с бубном. Ничего подобного в SDCC я не встречал (издержки CP/M?):
http://i.piccy_.info/i9/47d35c13d8ebac6e796794d4b6030cb0/1484741600/13760/1065564/HelloAsm.png
Вопрос к Sergey и Sayman: насколько безопасно отрезать ВСЕ коды 1A в конце бинаря? (не выйдет ли, что последний байт с этим кодом будет нужным?)
http://i.piccy_.info/i9/cacaf63eb9da25a475aeb1ed47f6465c/1484741620/8573/1065564/1A.png
P.S. Можно я плюну на лысину авторам подобных высказываний?
Вы еще Си не нашли, тогда вам к нам HI-TECH Z80 C Compiler. Занимает 30кБ +30кБ +30кБ. Адекватен. Понятен. Доступен всем!!!
ВО!!!. Академичные алгоритмы мало интересны для Z80 если они не могут переплюнуть разработку 83 года) Тем более не адекватностью генерируемого кода зашкаливает у новоделов.Умиляшка просто. Ох уж эти теоретики, мля...
- - - Добавлено - - -
Hi-Tech C берёт код входа в программу и выхода в ОС из библиотеки libc.lib, наверное как-то можно заменить эти подпрограммы на пустые. Но возня. Если libc.lib не подать параметром на вход линкера, получаем:
HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
undefined symbols:
cret
ncsv
indir
Код от SDCC. Для сравнения
_main::
ld a,#'H'
rst 16
ld a,#'E'
rst 16
ld a,#'L'
rst 16
ld a,#'L'
rst 16
ld a,#'O'
rst 16
retНи одного лишнего байта.
Ладно, это конечно не совсем честное сравнение, до Си мы так и не дошли.
- - - Добавлено - - -
Нашёл исходники библиотек Hi-Tech C v3.09, прикладываю.
59454
Вот и код для cret, ncsv и indir. Оказывается, он аллокирует количество байт на стеке, указанное в переменной, которая живёт у нас по адресу 25003 (после CALL на нашу main).
global csv,cret,indir, ncsv
psect text
csv: pop hl ;return address
push iy
push ix
ld ix,0
add ix,sp ;new frame pointer
jp (hl)
cret: ld sp,ix
pop ix
pop iy
ret
indir: jp (hl)
; New csv: allocates space for stack based on word following
; call ncsv
ncsv:
pop hl
push iy
push ix
ld ix,0
add ix,sp
ld e,(hl)
inc hl
ld d,(hl)
inc hl
ex de,hl
add hl,sp
ld sp,hl
ex de,hl
jp (hl)А вот, например, зацените ABS:
; abs(i) returns the absolute value of i
global _abs
psect text
_abs:
pop de ;Return address
pop hl
push hl
push de
bit 7,h ;Negative?
ret z ;no, leave alone
ex de,hl
ld hl,0
or a ;Clear carry
sbc hl,de
retДаже сходу хочется поменять "ld hl,0 : or a" на "xor a : ld l,a : ld h,a". Впрочем, мы с вами выяснили, что правильный ABS для слов выглядит так (http://zx-pk.ru/threads/27257-abs-i-sgn-v-mashkode.html?p=896276&viewfull=1#post896276). Для Спектрума нужно переписать библиотеки заново. Есть желающие окунуться в дружественный мир хайтех Си? ;-)
Installing the HI-TECH Z80 C Compiler for CP/M (http://techtinkering.com/2008/10/22/installing-the-hi-tech-z80-c-compiler-for-cpm/)
Странное знакомство. По идее вызова функции BDOS (http://www.seasip.info/Cpm/bdos.html) хватает.
- - - Добавлено - - -
Даже сходу хочется поменять "ld hl,0 : or a" на "xor a : ld l,a : ld h,a"
а флаги не потеряются, не?
Oleg N. Cher
19.01.2017, 12:56
Да и пусть себе теряются, компилятор не ждёт от функции сохранности флагов (и правильно делает).
Шынни, мне CP/M не интересна как таргет, вместо этого хочу приспособить компилятор для разработки под Спектрум, а тут BDOS нет.
- - - Добавлено - - -
Продолжим исследования. Хайтех для входа в любоую функцию генерирует:
CALL ncsv
DW 0 ; Сколько байт резервировать на стеке для локальных переменных
FnBody: ... ; Тут начинается сама функция
; А заканчивается она не RET, а
JP cretСпишем на то, что хайтек - компилятор однопроходный. И не знает на момент генерации кода входа в функцию, сколько байтов надо выделить на стеке для лок. переменных. Это он узнаёт уже потом.
SDCC же многопроходный, поэтому вместо вызова фрейма входа и выделения 0 байтов на стеке он просто вызывает функцию напрямую. И она возвращается по RET.
Я не готов сходу дать список отличий Hi-Tech C v3.09 и SDCC, но в этом SDCC сильно лучше. Вызов функций - вещь базовая, и она должна быть устроена максимально производительно. Возражения?
SDCC с ключиком --opt-code-size генерит такой вход в процедуру:
call ___sdcc_enter_ix
push af
push af ; Надо выделить 4 байта на стеке
...
ld sp, ix
pop ix
retC ключиком --opt-code-speed:
push ix
ld ix,#0
add ix,sp
push af
push af ; Надо выделить 4 байта на стеке
...
ld sp, ix
pop ix
ret
Да и пусть себе теряются, компилятор не ждёт от функции сохранности флагов (и правильно делает).
Шынни, мне CP/M не интересна как таргет, вместо этого хочу приспособить компилятор для разработки под Спектрум, а тут BDOS нет.
А версию для msdos не пробовали?
Даже сходу хочется поменять "ld hl,0 : or a" на "xor a : ld l,a : ld h,a".
При этом, процедура перестанет непортить аккумулятор. Ухудшит это оптимизацию?
Oleg N. Cher
19.01.2017, 19:25
Версию для ms-dos есть желания попробовать, руки не дошли. Но вроде как она сильно лучше, где-то в теме "Ищу Си для Z80" проскакивала ссылка на результаты сравнения качества кода для разных Z80-компилеров, не могу найти.
Reobne, ни один известный мне компилятор Си не воспользуется для оптимизации тем фактом, что регистр A не портится внутри функции. Кроме SDCC - если указать __preserves_regs(a). Но это философский вопрос, что лучше - меньше тактов или не портить A.
- - - Добавлено - - -
Не, вру. z88dk тоже имеет модификатор __preserves_regs, он оттуда в SDCC и пришёл. Но неясно качество такой оптимизации...
просто забавно, что из Си вываливается.
сравните atol для z88 и HiTech
Alcoholics Anonymous
19.01.2017, 20:32
HiTech CP/M 3.09 (from zip posted by Oleg)
#include <ctype.h>
long
atol(s)
register char * s;
{
long a;
unsigned char sign;
while(*s == ' ' || *s == '\t')
s++;
a = 0;
sign = 0;
if(*s == '-') {
sign++;
s++;
}
while(isdigit(*s))
a = a*10L + (*s++ - '0');
if(sign)
return -a;
return a;
}
Написанное в C и использует общий 32-битного умножения для каждой итерации.
Written in C and uses a general 32-bit multiply for each iteration.
Z88DK 1.99B (new c library)
; ================================================== =============
; Dec 2013
; ================================================== =============
;
; long atol(const char *buf)
;
; Read the initial portion of the string as decimal long and
; return value read. Any initial whitespace is skipped.
;
; ================================================== =============
SECTION code_clib
SECTION code_stdlib
PUBLIC asm_atol
EXTERN l_eat_ws, l_eat_sign, l_neg_dehl, l_atoul
asm_atol:
; enter : hl = char *buf
;
; exit : bc = char *buf (next unprocessed char, could be digit on overflow)
; dehl = long result
; carry set on overflow (dehl clamped to LONG_MAX or LONG_MIN)
;
; uses : af, bc, de, hl
call l_eat_ws ; skip over any initial whitespace
call l_eat_sign ; consume any leading sign
jr nc, not_negative ; if there was no minus sign
; negative sign found
call not_negative ; convert numerical part
jp nc, l_neg_dehl ; if no overflow, negate result
inc de
inc hl ; dehl = LONG_MIN = $80000000
ret
not_negative:
ex de,hl
call l_atoul ; unsigned long conversion
jr c, overflow ; unsigned overflow
bit 7,d ; check for signed overflow
ret z
scf ; indicate signed overflow
overflow:
ld de,$7fff
ld h,e
ld l,e ; dehl = LONG_MAX = $7fffffff
ret
.....
.....
SECTION code_clib
SECTION code_l
PUBLIC l_small_atoul
l_small_atoul:
; ascii buffer to unsigned long conversion
; whitespace is not skipped
; char consumption stops on overflow
;
; enter : de = char *
;
; exit : bc = & next char to interpret in buffer
; dehl = unsigned result (0 on invalid input)
; carry set on unsigned overflow
;
; uses : af, bc, de, hl
ld c,e
ld b,d
ld de,0
ld l,e
ld h,d
dec bc
push de
push hl
loop:
pop af
pop af
inc bc
ld a,(bc)
sub '0'
ccf
ret nc
cp 10
ret nc
push de
push hl
add hl,hl
rl e
rl d
jr c, overflow_0
push de
push hl
add hl,hl
rl e
rl d
jr c, overflow_0
add hl,hl
rl e
rl d
jr c, overflow_0
ex de,hl
ex (sp),hl
add hl,de
pop de
ex (sp),hl
adc hl,de
ex de,hl
pop hl
jr c, overflow_1
add a,l
ld l,a
jr nc, loop
inc h
jr nz, loop
inc e
jr nz, loop
inc d
jr nz, loop
overflow_1:
pop hl
pop de
scf
ret
overflow_0:
pop af
pop af
jr overflow_1
Написано в ассемблере и использует сдвиги для умножения в каждой итерации. Эта версия также проверяет наличие переполнения или сгущенного и заглавные буквы результат соответствующего макс или мин значений.
Реализация z88dk, вероятно, немного больше, но это считалось хорошим компромиссом для таких функций, как это, где скорость может оказать влияние на производительность больших программ. Существует также быстрый вариант библиотеки z88dk, который использует "l_fast_atoul" вместо "l_small_atoul". Разница является быстрая версия пытается вычислить результат в 16 бит, а затем перемещается только до 32 бит, когда число становится большим.
Я ожидаю версию z88dk быть намного быстрее; если вас интересует, и вы можете дать мне двоичный (сырой z80, а не ф / м зависит) и Тест С программы я могу время два для сравнения. Существует утилита "ticks" в z88dk, который может измерять Z80 циклы точно.
Written in asm and uses shifts for multiplication in each iteration. This version also checks for overflow or underflow and caps the result to respective max or min values.
The z88dk implementation is probably a little bit bigger but that was thought a good compromise for functions like this where speed can have an impact on the performance of large programs. There is also a fast variant of the z88dk library that uses "l_fast_atoul" instead of "l_small_atoul". The difference is the fast version tries to compute the result in 16 bits first and then only moves to 32 bits when the number becomes large.
I expect the z88dk version to be a lot faster; if you are interested and you can give me a binary (raw z80, not cp/m dependent) and a test c program I can time the two for comparison. There is a utility "ticks" in z88dk that can measure z80 cycles exactly.
Oleg N. Cher
19.01.2017, 20:44
Hitech C v7.50 очень редко производит более быстрый код, чем z88dk/sdcc во всех испытаниях я сделал, так что я хотел бы, чтобы скомпилировать двоичный для вас попробовать.
Вы можете увидеть результаты некоторых тестах мы запускаем, в том числе Dhrystone 2.1 и Whetstone 1.2, здесь: http://www.z88dk.org/wiki/doku.php?id=temp:front#dhrystone_2.1
Alcoholics Anonymous, can I download an "official" build of zsdcc (z88-sdcc) for Windows? Or, I must patch and rebuild it manually?
Alcoholics Anonymous
19.01.2017, 21:24
Не, вру. z88dk тоже имеет модификатор __preserves_regs, он оттуда в SDCC и пришёл. Но неясно качество такой оптимизации...
Я вижу его влияние на сгенерированный код; это небольшая, но она есть. Есть много вещей, которые имеют небольшое влияние, но когда вы добавляете их все, вы в конечном итоге с чем-то намного лучше.
I see its impact in the generated code; it is small but it is there. There are a lot of things that have a small impact but when you add them all up, you end up with something a lot better.
- - - Добавлено - - -
Alcoholics Anonymous, can I download an "official" build of zsdcc (z88-sdcc) for Windows? Or, I must patch and rebuild it manually?
Yes you can. We build binaries for windows and mac osx. Linux users have to build it themselves.
You can grab the latest by downloading a nightly build ( http://nightly.z88dk.org/ ). These packages are complete and are built every night and will contain the latest changes and built binaries. Click on the "z88dk-win32-latest.zip" link right at the top and unzip/install as described here: https://www.z88dk.org/wiki/doku.php?id=temp:front#windows
If you have set up github, we don't put the binaries in z88dk/bin but you can copy the binaries from z88dk/bin in the download above and paste them into your github/z88dk/bin directory. Set the environment variables as described in the install instructions link above and you should be ok to compile.
After setting up the environment variable ZCCCFG and the path to point at z88dk/bin, you can compile out of a command prompt.
Some hints:
Translate to assembler for zx:
zcc +zx -vn -a -clib=sdcc_iy -SO3 --max-allocs-per-node200000 --opt-code-size test.c
--opt-code-size is optional
Change -vn to -v if you want to see what the compiler is doing
Add --c-code-in-asm if you want to see C statements interspersed with the output asm
Don't forget --fsigned-char if you want chars to be signed by default
Add -lm if using floats (use float_t or double_t instead of float or double to get rid of warnings)
Equivalent with sdcc:
sdcc -mz80 -S --max-allocs-per-node200000 --opt-code-size test.c
Add --reserves-regs-iy to be exactly equivalent to the z88dk compile but this may worsen sdcc's output.
Add -lm if using floats.
Don't forget --fsigned-char if you want chars to be signed by default
An asm translation will only show the C code translated. Library code is rooted here: https://github.com/z88dk/z88dk/tree/master/libsrc/_DEVELOPMENT and there is an EXAMPLES directory there with some programs to try (compile lines at top of .c)
Alcoholics Anonymous, What about "banked" memory for "ZX 128 computers" ? I know, its very difficult
for example
http://www.softools.com/zilogwinide.htm
https://www.google.ru/url?sa=t&rct=j&q=&esrc=s&source=web&cd=11&cad=rja&uact=8&ved=0ahUKEwiv2_zeqdHRAhXlK5oKHcguCD0QFghWMAo&url=http%3A%2F%2Fwww.zilog.com%2Fforce_download.ph p%3Ffilepath%3DYUhSMGNEb3ZMM2QzZHk1NmFXeHZaeTVqYjI wdlpHOWpjeTk2TVRnd0wzTnZablJ2YjJ4ekxuQmtaZz09&usg=AFQjCNF2U2z78tfp3qtayRBf0wXpu_7Esg&sig2=kjTbRazTVAD4gCJhNlepmg&bvm=bv.144224172,d.bGs
Alcoholics Anonymous
21.01.2017, 00:29
Alcoholics Anonymous, What about "banked" memory for "ZX 128 computers" ? I know, its very difficult
for example
http://www.softools.com/zilogwinide.htm
Yes we are heading in that direction. z80asm, z88dk's assembler / linker, is actively developed.
Right now, with a little work, you can manually generate bankswitched programs. Not as easy as doing it automatically as you still have to manually decide what goes where but the z88dk tools will help you to solve many of the difficulties. You can place code and data in specific memory banks easily (the c compilers can only place code and rodata but we will fix that; the current workaround is to define variables with correct section assignment from a separate asm file). You can get the tools to output a list of defines for all public functions and data and use that as a reference when doing cross banking calls. The tools support command-line ordered linking; in other words you can change the address of common functions depending on what part of the project is being compiled. So, for example, if you put printf in one bank then -g when printf is compiled will give its address. Then you can create a trampoline in the common area that changes banks, calls that printf, restores banks and returns. For all banks not containing printf, you would compile against another set of defines that would do something like "defc printf = 0x8000 ; printf trampoline" so that calls to printf from other banks go through the trampoline code and there you have a cross bank call.
But for most cases, 128 programming is much simpler -- you have extra data in the extra banks or you have code in the extra banks that does not call across banks. And this can be done now very easily. Pietro bros is an example that puts the AY code and sound effects into a separate 128 bank.
Да, мы движемся в этом направлении. z80asm, z88dk в ассемблер / линкер, активно развивается.
Прямо сейчас, с небольшим количеством работы, вы можете вручную сгенерировать bankswitched программы. Не так просто, как это делать автоматически, как вам все равно придется вручную решить, что идет туда, куда но и z88dk инструменты помогут вам решить многие трудности. Вы можете разместить код и данные в отдельных банках памяти легко (с-компиляторы могут только размещать код и rodata, но мы исправим это, текущий обходной путь заключается в определении переменных с правильным назначением раздела из отдельного файла ASM). Вы можете получить инструменты для вывода списка определяет для всех государственных функций и данных, а также использовать его в качестве эталона при выполнении перекрестных банковских вызовов. Инструменты поддержки командной строки заказал связь; другими словами, вы можете изменить адрес общих функций в зависимости от того, какая часть проекта составляется. Так, например, если вы положили Printf в одном банке, то -g при компиляции Printf даст свой адрес. После этого вы можете создать трамплин в общей зоне, которая изменяет банки, вызовы, которые Printf, восстанавливает банки и возвращается. Для всех банков, не содержащих Printf, ты скомпилировал бы против другого набора устанавливает, что бы сделать что-то вроде "defc Printf = 0x8000; Printf батут", так что вызовы PRINTF от других банков пройти через код батут и там у вас есть вызов перекрестного банка ,
Но в большинстве случаев, 128 программирование намного проще - у вас есть дополнительные данные в дополнительных банках или у вас есть код в дополнительных банках, которые не звонят по банкам. И это может быть сделано сейчас очень легко. Пьетро Bros является примером, который помещает код AY и звуковые эффекты в отдельный 128 банка.
.
- - - Добавлено - - -
you can manually generate
Are You used softools's compiler ?
Alcoholics Anonymous
21.01.2017, 18:50
.
Are You used softools's compiler ?
No I haven't. I have only read about it online and in the paper you linked.
The automatic linking of bankswitched programs is something we would like to do but it will take some more development and thought. Soft Tool only had to deal with one memory model - the z180's - which it then applied to the z80. We have a more complicated case in that there are machines with varying memory map, some with holes in the middle of ram, and varying banking schemes. We also have to keep an eye on recent C standard propositions -- there is an embedded technical report that specifies how banked variables and functions can be accessed from C. So a solution has to be more general and the pieces for that will come together after we've got a smooth way to do the banking manually. Once the manual banking is down we will have to work on the linker to optimally assigned code and data to require the least amount of memory and least amount of bankswitching given a target's specified memory map.
---
Нет у меня нет. Я только читал об этом в Интернете и в статье вы связаны между собой.
Автоматическое связывание bankswitched программ является то, что мы хотели бы сделать, но это займет еще некоторое развитие и мысль. Soft Tool только приходилось иметь дело с одной модели памяти, - установка Z180 - который он затем применяется к z80. У нас есть более сложный случай в том, что есть машины с различной картой памяти, некоторые с отверстиями в середине барана, и различные банковские схемы. Мы также должны следить за последних стандартных С предложениями - есть встроенный технический отчет, который определяет, как накренился переменные и функции могут быть доступны из C. Таким образом, решение должно быть более общим и куски для, которые придут вместе после того, как у нас есть плавный способ сделать банковские операции вручную. После того, как руководство банковского вниз мы будем работать над линкера оптимально присвоен код и данные требуют наименьшего количества памяти и наименьшее количество bankswitching учитывая указанную карту памяти, который цели.
Alcoholics Anonymous, its fоr eхample, 30 days free, its zilog party, are you never used ZDS?
Alcoholics Anonymous
24.01.2017, 00:37
Alcoholics Anonymous, its fоr eхample, 30 days free, its zilog party, are you never used ZDS?
For my 30 days I am waiting until I have a large set of benchmarks to run. I'd like to spend that time taking a look at code quality.
I do have ZDS 3.68 but I have never been able to compile anything. The package they offer for download is missing dlls (z180.dll for me) and the support has no idea what I am talking about. I think it is too old for Zilog to care anymore :( Have you managed to get ZDS 3.68 to work at all?
Для моих 30 дней я жду, пока я не большой набор тестов для запуска. Я хотел бы провести это время взглянуть на качество кода.
У меня есть АРС 3,68, но я никогда не был в состоянии собрать что-нибудь. Пакет, который они предлагают для скачивания отсутствует DLLs (z180.dll для меня) и поддержка понятия не имеет, о чем я говорю. Я думаю, что слишком стар для Zilog, чтобы заботиться больше :( Вы сумели получить АРС 3,68 работать
Oleg N. Cher
26.01.2017, 01:08
Продолжаем. Мне удалось собрать минимальную подсистему ZXDev3, которая работает с Hi-Tech C v3.09 вместо SDCC. С неизменным рантаймом в виде cret, ncsv и indir смирился (его не вырезает даже оптимизатор). Правда, я слегка переписал CSV.AS, убрал оттуда обязательное сохранение регистра IY для каждой процедуры (пусть сама решает, сохранять ли его). И собрал в библиотеку LIBC2.LIB
Странное дело, но похоже, что каждая функция в момент входа в неё держит на стеке сохранённое значение IX (а в случае немодифицированного CSV.AS и IY тоже) с самого верху. То есть, чтобы добраться до параметров, обычное:
POP HL
POP BC
PUSH BC
PUSH HLу меня не срабатывает. Нужен какой-то хитрый способ описания ассемблерных функций? Или мириться с тем, что возвращаться надо не по RET, а по JP cret? Плюс иметь затруднённый доступ к аргументам? Как же быть?
59539
Код функции печати строки PRSTR у меня сейчас такой:
void Basic_PRSTR_C_ROM_fastcall (unsigned char *str) {
# asm
LD IY, 5C3AH
POP IX ; Без этого слетает. А в случае стандартного LIBC.LIB нужен и POP IY
POP HL
POP BC
PUSH BC
PUSH HL
PRSTRstd$: LD A, (BC)
OR A
RET Z
RST 16
INC BC
JR PRSTRstd$
# endasm
}
http://i.piccy_.info/i9/4c23ba43d8f08e9a5300e1887478020e/1485381940/23532/1065564/Hello.png
Oleg N. Cher
28.01.2017, 01:43
Какой будет аналог этого кода в Hi-Tech C v3.09 ? Просьба не писать наобум, а давать только рабочий код.
#define Basic_Init() __asm di __endasm
Вот так не работает:
# define Basic_Init() /**/ \
#asm \
DI \
#endasm( напоминаю, что в хайтек Си решётку можно ставить только в первой колонке строки )
http://i89.fastpic.ru/big/2017/0128/44/47199405e05495e2be1fe7ff21968244.png
согласно руководству (http://www.z80.eu/downloads/z80doc.zip)
look at code quality.
it would be excellent, You have more experience. If You dont have free time, I can help you, if you send example or source code for testing.
Easy way have more 30 days, have copy clear virtual system for re intsall softotols
The package they offer for download is missing dlls (z180.dll for me)
Yes, Zilog cut its, for softotools as commercial part and ZDS C compiler for ez80, its have 2 model, "large", for 24 bit adresss and "small" 64K segments Z80.
- - - Добавлено - - -
Oleg N. Cher,
Прошу извинить за столь бесцеремонное вторжение в тему
Oleg N. Cher
28.01.2017, 16:00
Шынни, спасибо, но лично мне ничего нового Вы не сообщили. Вопрос был: как обернуть этот DI в макрос?
Вопрос был: как обернуть этот DI в макрос?
Какой будет аналог этого кода в Hi-Tech C v3.09 ?
Теперь это так называется? А с какой целью нужно обернуть?
#define Basic_Init() __asm di __endasm
для хайтеха в мануале была конструкция вида:
#define blah() asm(" di")
но из-за какого то бага в компиляторе эта конструкция не работает. так что подобное для 3.09 не работает. для досоввой версии оно работает.
чтобы избавится от вызова ncsv надо использовать оптимизатор, он его меняет на csv, но оптимизатор съедает ваш асмовый код. поэтому для хайтеха будет плохой практикой в одном файле писать на си и на асме и пихать этот файл оптимизатору. выносите асмы все в отдельный асм файл, а си файлы прогоняйте через оптимизатор.
и делать pop ix не обязательно (первый съём со стека = съём адреса возврата, это правило работает и в sdcc), но желательно ix сохранять, а при выходе восстановить.
скачайте наработки Error404 в его темах про Орион, там у него много примеров для сборки кода да и самого кода предостаточно для понимая.
Oleg N. Cher
29.01.2017, 03:22
Теперь это так называется? А с какой целью нужно обернуть?Раз Вы цитируете меня, то не нужно передёргивать и вырывать фразу из контекста. Надо так:
Какой будет аналог этого кода в Hi-Tech C v3.09 ?
#define Basic_Init() __asm di __endasm
Разве это не:
Вопрос был: как обернуть этот DI в макрос??
- - - Добавлено - - -
Sayman, насколько я понял, asm("команда") в хайтеке версии 3.09 вообще ещё не реализовано. Док касается более новых версий.
Что до зачем это нужно. Я пытаюсь повторить на хайтек компилере то, что у меня уже реализовано на SDCC. Если распихивать то, что нельзя похабить оптимизатору непременно в отдельные .asm-файлы и запихивать в библиотеки (а, видимо, так и придётся сделать), а в Си-файлах писать только на Си, то об эффективности, легко достижимой в SDCC, придётся забыть. А, возможно, и о некоторых возможностях конфигурирования библиотек "на лету" (без перекомпиляции).
Про хайтек я понял то, что все сишные функции всегда вызываются через csv или ncsv, с PUSH IY/IX, и этот код не вырезает даже оптимизатор. Если написать пустую ф-цию main, для неё будет сгенерен один RET, но кусок кода из CSV.AS всё равно будет прилинкован. Таким образом, доступ ко всем аргументам и локальным переменным внутри сишной функции происходит с учётом сохранённых IY/IX на стеке. То есть мои манипуляции с обходом сохранения IY ни к чему хорошему не приводят, только к багам.
Отказаться от обязательного автоматического сохранения IY/IX можно только в функциях, написанных на ассемблере (не встроенном!). В сишных - НЕЛЬЗЯ.
Oleg N. Cher
31.01.2017, 00:56
Выкладываю подсистему ZXDev3, основанную на Hi-Tech C v3.09 вместо SDCC. Это мой реверанс в сторону любителей сего компилятора. Я реализовал всего три процедуры из библиотеки Basic, убедился, что это возможно, и мне стало неинтересно.
ZXDev3 называется так по версии Hi-Tech C. Основанная на седьмой может называться ZXDev7. Если когда-нибудь будет сделана подсистема, основанная на IAR C, она будет называться ZXDevI. Но всё это я не планирую. Планирую осваивать z88dk, тем более что Alcoholics Anonymous очень дружелюбен и отзывчив, отвечает на все вопросы очень подробно и прислушивается к хорошим советам. Да, отдельная подсистема ZXDevZ не планируется, вместо этого zsdcc будет встроен в основную подсистему ZXDev.
В одно нажатие F12 собирается вот это (запускается компиляция в эмуляторе CP/M, делается tap и запускается):
(*$MAIN*) MODULE HelloC; IMPORT b := Basic;
BEGIN
b.BORDER(3);
b.COLOR(4); b.PRSTR("Hello ");
b.COLOR(5); b.PRSTR("Hello ");
b.COLOR(6); b.PRSTR("Hello ");
END HelloC.Бинарь сей прожки занимает 179 байт. Меньше мне сделать не удалось (в SDCC легко).
Результирующий код выглядит обычно, параметры передаются на стеке (в SDCC иногда можно в регистрах). В целом довольно нормально, жить можно. Больше ничего в этом направлении делать не планирую. Разве что попробую собирать хайтеком порт игры Dash, чисто чтобы сравнить качество кода. Но я уверен, оно будет сильно ниже, чем у zsdcc.
59591
Это снапшот. По мере дальнейшей разработки он будет устаревать. Актуальная версия будет жить здесь:
https://github.com/Oleg-N-Cher/XDev/tree/master/ZXDev3
Баг-репорты и пожелания приветствуются.
Если будете что-то делать в плане библиотек для Hi-Tech C v3.09, я заинтересован включить эти наработки в подсистему ZXDev3.
Alcoholics Anonymous
03.03.2017, 09:37
it would be excellent, You have more experience. If You dont have free time, I can help you, if you send example or source code for testing.
Easy way have more 30 days, have copy clear virtual system for re intsall softotols
Totem (or anyone else) are you interested in running some benchmarks for compilers I don't have access to?
I'm getting ready to run benchmarks again and I'd like to compare against as many z80 compilers as possible. I'd also like to try z180 compiles too. We don't have a timer for the z180 yet but if we can get some binaries out of that we can maybe time them in the future when our simulator is updated.
Currently the benchmarks we have are: dhrystone 2.1, whetstone 1.2, sieve and pi. I'd like to add Coremark this time around but we are not allowed to distribute the source code for this one. If anyone has suggestions for more benchmarks, I'm happy to consider them.
The source code for these benchmarks can be found in: https://github.com/z88dk/z88dk/tree/master/libsrc/_DEVELOPMENT/EXAMPLES/benchmarks
I've cleaned up the code and am in the process of making sure they run on z88dk. Dhrystone 2.1 is finished (the z88dk/zsdcc score is 321) but the others will be updated in the next day or two as they are verified to be working.
I have access to sccz80, zsdcc, sdcc, hitech v309 cpm, hitech v750 msdos for running the benchmarks. I will try Zilog's tools as well but I don't know if I can persuade them to produce code yet. If anyone has more compilers available and you are interested in running the benchmarks, let me know. If you're an expert at getting good performance out of hitech c, you may do a better job than me and I'd be interested in hearing from you too.
=====
[B] Тотем [/ B] (или кто-либо другой) вы заинтересованы в запуске некоторых тестов для составителей у меня нет доступа?
Я готовлюсь снова запустить тесты, и я хотел бы сравнить против как многие Z80 компиляторов, как это возможно. Я также хотел бы попробовать Z180 компилирует тоже. У нас нет таймер для Z180 еще, но если мы можем получить некоторые двоичные файлы из этого мы можем, возможно, их тайм в будущем, когда наш тренажер обновляется.
В настоящее время у нас есть тесты являются: Dhrystone 2.1, оселок 1.2, решето и пи. Я хотел бы добавить CoreMark в этот раз, но мы не имеем права распространять исходный код для этого. Если у кого есть предложения по более критериев, я рад рассмотреть их.
Исходный код для этих тестов можно найти в: https://github.com/z88dk/z88dk/tree/master/libsrc/_DEVELOPMENT/EXAMPLES/benchmarks
Я очистил код и нахожусь в процессе убедившись, что они работают на z88dk. Dhrystone 2.1 закончена (счет z88dk / zsdcc составляет 321), а остальные будут обновлены в следующий день или два, как они проверяются, чтобы работать.
У меня есть доступ к sccz80, zsdcc, SDCC, Hitech V309 имп, Hitech V750 MSDOS для запуска тестов. Я попытаюсь инструменты Zilog как хорошо, но я не знаю, смогу ли я убедить их производить код еще. Если у кого есть больше компиляторы доступны и вы заинтересованы в проведении контрольных показателей, дайте мне знать. Если вы являетесь экспертом в получении хорошей производительности из Hitech C, вы можете сделать лучше, чем у меня, и мне было бы интересно услышать от вас тоже.
Error404
21.03.2017, 16:13
У меня есть доступ к sccz80, zsdcc, SDCC, Hitech V309 имп, Hitech V750 MSDOS для запуска тестов. Я попытаюсь инструменты Zilog как хорошо, но я не знаю, смогу ли я убедить их производить код еще. Если у кого есть больше компиляторы доступны и вы заинтересованы в проведении контрольных показателей, дайте мне знать. Если вы являетесь экспертом в получении хорошей производительности из Hitech C, вы можете сделать лучше, чем у меня, и мне было бы интересно услышать от вас тоже.
Что-то не видел раньше эту тему. Вставлю свои пять копеек.
Лично я не особенно понимаю весь этот спичь от Олега за производительность, использование лишнего индексного регистра, jp вместо ret и прочие изыски, которые более выглядят как желание докопаться в пользу более полюбившегося варианта компилятора, уникальные особенности которого позволяют где-то чуть меньше трудиться, чем делая универсальный и в силу этого очевидный для "человека с улицы" вариант. Для меня гораздо важнее предсказуемость компилятора, которая прямо проистекает от того насколько порядок голове у его автора(ов), и общеупотребимость (что прямо противоположно "уникальным особенностям") - "сел и поехал". Остальное (если вдруг действительно лишний джамп все замедлил) решаемо заменой процессора на с частотой побольше.
По первому пункту у SDCC все было очень грустно (по крайней мере в последней версии SDCC что я использовал - 2.9х - заведомо исправный код компилировался без ошибок и варнингов, но не работал, а проходить 25кб консольным отладчиком - нуегонафиг), тогда как Hitec тот же код собирал и он работал (при в полтора меньшем размере кода на выходе). Возможно, сейчас стало получше, но эксперимениты с любительскими клонами SmallC я завязал. По второму пункту тоже очевидно: ANSII компилятор (т.е. как я понимаю Z88dk сразу выпадает) с максимум полдюжиной ключей и готовым выхлопом под наиболее распространенныю платформу для которой есть 100500 эмуляторов (CP/M) куда как проще освоить и дальше видоизменять {адреcа посадки и чего угодно}, чем компилер с дикой кучей ключей и "изкоробки" не компилирующий в среду, которую должен знать и уметь любой уважающий себя компилер для Z80 (что тоже говорит о кругозоре авторов). А так то конечно да - имея под попой PC986 с биллионами байт памяти и биллионами же герц тактовой казалось бы не написать нормальный компилятор С?! Да за пояс заткнем эти CP/M c их 64кб, дискеткой в 400кб и смешным процессором. :))) #скоро
Вот тут (https://github.com/serge-404/U.Z.I.X.)лежит моя адаптация UZIX где в качестве компилятора использован HitechC v3 (https://github.com/serge-404/HI-TECH-C-V3.09)(+эмулятор+make). Там же есть библиотеки в исходниках (libc, libf), мейкфалы, на случай если кому пригодится в качестве примера или для какого дерибана. Все выложено, в том числе в темах на форуме, стоило столько шишек по второму кругу собирать чтобы потом обхаять (когда можно было взять готовое и не париться), что как бы характеризует.
Кстати из смешного, FUZIX (который не сложнее Uzix) где компилятором взяли SDCC, AFAIK собирается только одной определенной версией этого чудесного компилятора, с набором костылей (к компилятору понятно).
Oleg N. Cher
22.03.2017, 04:14
Знаете что больше всего угнетает. Пиление на коленке никому не нужного uzix вместо того чтобы сделать, например, полезный баг-репорт в копилку SDCC. Таким образом, потратив силы не на самоудовлетворение, а на пользу для ещё кого-то, своих же собратьев по перу. А не лить помои на SDCC "потому что хатех запулился, а SDCC не запулился".
Мой же выбор очевиден. Вылизали хайтех? Ну да, вылизали, это же коммерческий компилятор. Развивается хайтех? А вот то-то же.
- - - Добавлено - - -
Могу добавить, что SDCC с версии 3.6.0 очень стабилен, я давно уже не сталкиваюсь с багами. За всё время, которое я работаю с SDCC, а это 6-7 лет, качество кода выросло, полезных фич добавилось, компилятор стал намного лучше. Вот о чём надо писать, а не "старая версия весьма баговита, а с тех пор я не пробывал".
А если есть баги, то в студию их. Кстати, некоторые "баги", с которыми столкнулся я, - они вовсе не в SDCC. Просто программа на Си переносима весьма условно, а на деле может быть масса тонких несостыковок. И чем аффтар поручится, что его вопли связаны именно с багами в компиляторе? Ему же лень в этом ковыряться.
Alcoholics Anonymous
26.03.2017, 23:59
Что-то не видел раньше эту тему. Вставлю свои пять копеек.
Лично я не особенно понимаю весь этот спичь от Олега за производительность, использование лишнего индексного регистра, jp вместо ret и прочие изыски, которые более выглядят как желание докопаться в пользу более полюбившегося варианта компилятора, уникальные особенности которого позволяют где-то чуть меньше трудиться, чем делая универсальный и в силу этого очевидный для "человека с улицы" вариант. Для меня гораздо важнее предсказуемость компилятора, которая прямо проистекает от того насколько порядок голове у его автора(ов), и общеупотребимость (что прямо противоположно "уникальным особенностям") - "сел и поехал". Остальное (если вдруг действительно лишний джамп все замедлил) решаемо заменой процессора на с частотой побольше.
Если это не встроенная система, то чаще всего процессорная плата z80 припаивается к материнской плате, а аппаратное обеспечение вокруг нее не может обеспечить более высокую тактовую частоту, поэтому замена процессора более быстрым вариантом не подходит большинству людей. Небольшие вещи, которые Олег рассказывает обо всех, складываются. Например, несколько небольших вещей, которые мы сделали в z88dk (например, callle и fastcall linkage), добавили к сохранению 1k в 40k скомпилированной программе. Нечего чихать. Эти другие коммерческие компиляторы также делают много мелких вещей, и у кого больше успехов, можно реально измерить только путем сбора тестовых примеров.
Я бы согласился с вами, что скорость не является проблемой номер один для компилятора, но приятно быть быстрее, другие приоритеты равны. Скорость не совсем неуместна, как вы предполагаете; Если бы это было так, вы были бы довольны программированием в основном. Цель состоит в том, чтобы быть достаточно быстрым (и, во-вторых, так быстро, как это разумно, учитывая ограничения). Я считаю, что скомпилированный размер программы гораздо более важен, если компилятор может удовлетворять удовлетворительной скорости. Например, существует около 40 игр, написанных на C для спектра (около 30-35 или около того с z88dk), и в любой нетривиальной игре размер памяти является проблемой. Любые разумные средства для уменьшения размера компиляции могут способствовать качеству игр.
Unless it's an embedded system, most often the z80 cpu is soldered onto the motherboard and the hardware around it cannot accommodate higher clock rates so replacing the cpu with a faster one is not an option for most people. The small things that Oleg talks about all add up. For example, several small things we did in z88dk (callee and fastcall linkage, for example) added up to saving 1k in a 40k compiled program. That's nothing to sneeze at. These other commercial compilers also do many small things and who's had more success can really only be measured by trying to compile test cases.
I would agree with you that speed is not really the number one concern for a compiler but it is nice to be faster, other priorities held equal. Speed is not totally irrelevant as you suggest however; if it was, you would be satisfied with programming in basic. The goal is to be fast enough (and secondarily as fast as is reasonable given constraints). I find that compiled program size is much more important once the compiler can meet satisfactory speed. For example, there are about 40 games written in C for the spectrum (about 30-35 or so with z88dk) and in any non-trivial game the memory size is a problem. Any reasonable means to get the compile size down can contribute to the quality of games produced.
По первому пункту у SDCC все было очень грустно (по крайней мере в последней версии SDCC что я использовал - 2.9х - заведомо исправный код компилировался без ошибок и варнингов, но не работал, а проходить 25кб консольным отладчиком - нуегонафиг), тогда как Hitec тот же код собирал и он работал (при в полтора меньшем размере кода на выходе). Возможно, сейчас стало получше, но эксперимениты с любительскими клонами SmallC я завязал.
Sdcc 2.9x давным-давно перед некоторыми существенными изменениями в генераторе кода z80 в sdcc. Я бы тоже не использовал 2.9x, однако нынешний sdcc намного лучше. У него все еще есть некоторые ошибки, особенно окружающие доступ к статическим переменным и --reserve-regs-iy, но они были решены в z88dk (не sdcc).
Главная проблема с sdcc заключается не в переводчике языка, а в библиотеке. Библиотека минимальна и написана на C. Любой, кто использует sdcc, останется с впечатлением, что многое отсутствует и будет разочаровано скоростью и объемом памяти. Опять же, проблема не в самом компиляторе. Когда вы разрешаете sdcc использовать библиотеки языков ассемблера z88dk, его производительность улучшается в несколько раз.
Конечно, я все еще вижу много возможностей для улучшения в компиляторе, но я вижу, что в каждом компиляторе, который я тестировал (hitech cpm 309, hitech cpm 750, iar 406a, z88dk / zsdcc, z88dk / sccz80, sdcc).
sdcc 2.9x is a long time ago before some significant changes in the z80 code generator in sdcc. I wouldn't have used 2.9x either, however the current sdcc is much better. It does still have some bugs especially surrounding access to static variables and --reserve-regs-iy but these have been solved in z88dk (not sdcc).
The main issue with sdcc is not in the language translator, it's in the library. The library is minimal and written in C. Anyone using sdcc will be left with the impression that a lot is missing and will be disappointed with speed and memory size performance. Again, the problem is not in the compiler itself. When you allow sdcc to use z88dk's assembly language libraries its performance improves by several times.
Of course, I still see a lot of room for improvement in the compiler but I see that in every compiler I've been testing (hitech cpm 309, hitech cpm 750, iar 406a, z88dk/zsdcc, z88dk/sccz80, sdcc).
По второму пункту тоже очевидно: ANSII компилятор (т.е. как я понимаю Z88dk сразу выпадает) с максимум полдюжиной ключей и готовым выхлопом под наиболее распространенныю платформу для которой есть 100500 эмуляторов (CP/M) куда как проще освоить и дальше видоизменять {адреcа посадки и чего угодно},
Справедливо, если вам нужен только ANSI-компилятор. Но я просто скажу, что не очень справедливо сравнивать z88dk / sccz80 (небольшой c-компилятор в z88dk) с другими компиляторами c. Эти другие компиляторы застыли в своем развитии ~ 20 лет назад. Sccz80 никогда не прекращал развиваться, поэтому вы можете рассматривать его как самый доступный небольшой компилятор c.
Z88dk также содержит zsdcc, который является улучшенным sdcc-z80. Это компилятор ANSI с исправлениями некоторых ошибок sdcc и многими оптимизациями глазок, которые улучшают вывод кода. Большие улучшения также возникают из-за использования z88dk-интерфейса и его задней части, что упрощает компиляцию программ и позволяет настраивать таргетинг на различные машины z80, просто изменяя переключатель компиляции. Он также получает доступ к библиотечным языкам ассемблера z88dk. Эти вещи улучшают производительность sdcc.
Fair enough if you only want a reasonably ansi compiler. But I'll just say it's not really fair to compare z88dk/sccz80 (the small c derived compiler in z88dk) with the other small c compilers. Those other compilers froze in their development ~20 years ago. sccz80 never stopped developing so you can regard it as the most advanced small c derived compiler available.
z88dk also contains zsdcc which is an improved sdcc-z80. That is an ansi compiler with fixes for some of sdcc's bugs and many peephole optimizations that improve the code output. Large improvements also come from using z88dk's front end and back end which makes it easy to compile programs and makes it possible to target different z80 machines just by changing a compile-line switch. It also gets access to z88dk's assembly language libraries. These things improve sdcc's performance a great deal.
чем компилер с дикой кучей ключей и "изкоробки" не компилирующий в среду, которую должен знать и уметь любой уважающий себя компилер для Z80 (что тоже говорит о кругозоре авторов). А так то конечно да - имея под попой PC986 с биллионами байт памяти и биллионами же герц тактовой казалось бы не написать нормальный компилятор С?! Да за пояс заткнем эти CP/M c их 64кб, дискеткой в 400кб и смешным процессором. :))) #скоро
Они (sdcc) не обращали внимания на эффективную реализацию некоторых структур данных. Оптимизация компиляторов гораздо сложнее изнутри и может потреблять гораздо больше памяти при анализе кода, чем любой компилятор, который может работать только в 64-разрядной системе. Лично, время работы компилятора - это не моя основная проблема, если я получаю что-то хорошее с другого конца. Это может иметь значение во время разработки, если оно замедляет работу, но вы всегда можете снизить уровень оптимизации, чтобы ускорить процесс или правильно разбить исходный код, чтобы вы могли использовать make-файл.
They (sdcc) didn't pay attention to efficient implementation of some data structures. Optimizing compilers are much more sophisticated internally and can consume a great deal more memory in doing code analysis than any compiler that is restricted to run on a 64k system. Personally, the compiler's running time is not my main concern as long as I get something good out the other end. It can matter during development if it slows you down but you can always reduce the optimization level to speed things up or properly partition your source code so that you can make use of a makefile.
Вот тут (https://github.com/serge-404/U.Z.I.X.)лежит моя адаптация UZIX где в качестве компилятора использован HitechC v3 (https://github.com/serge-404/HI-TECH-C-V3.09)(+эмулятор+make). Там же есть библиотеки в исходниках (libc, libf),
Hitech cpm v309 libf не является надежным. Он дает только точные результаты с плавающей запятой для + - * /. У всего остального есть большие ошибки. Я нашел это, когда выполнял несколько тестовых программ, содержащих операции с плавающей запятой. BTW, Hitech msdos v750 не может даже + - * /, все операции с плавающей точкой прослушиваются.
Я обнаружил, что у Hitech cpm v309 была самая быстрая реализация 32-битной плавающей библиотеки, но, как уже упоминалось, она хороша только для + - * /.
Hitech cpm v309 libf is not reliable. It only produces accurate floating point results for +-*/. Anything else has large errors in them. I found this while running several benchmark programs containing float operations. BTW, Hitech msdos v750 cannot even +-*/, all float operations are bugged.
I did find that Hitech cpm v309 had the fastest 32-bit float library implementation but, as mentioned, it is only good for +-*/.
Кстати из смешного, FUZIX (который не сложнее Uzix) где компилятором взяли SDCC, AFAIK собирается только одной определенной версией этого чудесного компилятора, с набором костылей (к компилятору понятно).
Я бы не согласился. Конечно, Fuzix сложнее, чем Uzix, потому что, помимо всего прочего, он должен поддерживать разные архитектуры, включая различные графические и текстовые терминалы с различными разрешениями. Uzix не так амбициозен. Однако я согласен с тем, что Fuzix будет намного меньше и быстрее, если использовать, например, z88dk / zsdcc. Но это потребует значительных изменений, чтобы добиться улучшений, потому что z88dk работает на уровне языка ассемблера, но Fuzix в настоящее время ориентирован только на C. Например, все заголовки z88dk используют атрибуты низкого уровня для изменения связи вызова функций вызова и сохранения информации о регистрации для вызова В функции языка ассемблера в библиотеке. Сейчас нет способа разместить это в системе сборки Fuzix.
I would disagree. Fuzix certainly is more complicated than Uzix because, among other things, it has to support different architectures including different graphics and text terminals with varying resolutions. Uzix is not as ambitious. However I do agree that Fuzix would be a lot smaller and faster if it used, say, z88dk/zsdcc. But it would require a lot of changes to gain improvements because z88dk operates at the assembly language level but Fuzix is currently geared only to C. For example, all of z88dk's headers use low level attributes to change function call linkage and register preservation information for calling into the assembly language functions in the library. There is no way to accommodate this in Fuzix's build system now.
Oleg N. Cher
27.03.2017, 13:52
Error404, понятно Вам? Нечего чихать. :-)
- - - Добавлено - - -
Любой, кто использует sdcc, останется с впечатлением, что многое отсутствует и будет разочаровано скоростью и объемом памяти.Добавлю от себя. Любой, кто использует ZXDev, свободен от библиотек SDCC и использует собственные машкодовые высокоэффективные библиотеки ZXDev.
OrionExt
28.03.2017, 02:03
А что делать не многим любителем которые писали софт под 2,9?. Любитель перемен)
- - - Добавлено - - -
Работайте дальше. А мы будем юзать тру – си. Для z80)
Oleg N. Cher, я уже приводил в пример evo dsk с его примерами. после перехода на современную версию sdcc проекты перестают собираться или собираются в нерабочий код. если не веришь, проверь сам и попробуй собрать того же "game_xnx". Есть исходники других игрушек под атм написанных на этом sdk, они в версиях старше 2.9.0 не собираются.
есть для теста исходник aes256 под z80. он тоже с ходу не собирается в последних версиях. зато в старой версии и с htc легко.
Alcoholics Anonymous
28.03.2017, 08:20
есть для теста исходник aes256 под z80. он тоже с ходу не собирается в последних версиях. зато в старой версии и с htc легко.
У меня не возникло проблем с компиляцией aes256 с помощью sdcc.
Вы можете увидеть, как я это сделал здесь:
https://drive.google.com/file/d/0B6XhJJ33xpOWS2g1a2NEempzdHc/view?usp=sharing
Sdcc / build.bat показывает, как я построил демонстрацию, используя sdcc и target cpm.
Z88dk / build.bat показывает, как я построил демонстрационную версию, используя zsdcc и целевые cpm и спектр.
Исходный код имел некоторые проблемы.
Во-первых, он использует синтаксис K & R для параметров функции. Я понимаю, почему он так поступил - большинство компиляторов эпохи CP / M не являются ansi и не могут делать правильный синтаксис функции. Синтаксис K & R был оставлен 30 лет назад, и sdcc не смог поддержать его, потому что это не важно. Я установил, что передача параметров должна быть ansi.
Во-вторых, demo.c не имеет прототипов функций для функций, экспортированных из aes256.c. Я подозреваю, что оригинальный автор включил aes256.c в demo.c и затем скомпилировал demo.c. Это связано с тем, что сложнее делать отдельную компиляцию на старых компиляторах. Я добавил прототипы отсутствующих функций и использовал отдельную компиляцию для sdcc и z88dk. Вы можете понять, почему отдельная компиляция сложнее для этих старых компиляторов, посмотрев на sdcc / make.bat - это также сложнее для sdcc. В z88dk / make.bat вы просто добавляете другой исходный файл в строку компиляции.
Если вы посмотрите на результаты, HTC v309 неправильно распечатает шестнадцатеричные цифры. Предполагается, что% x будет шестнадцатеричным регистром, но HTC игнорирует это и просто печатает шестнадцатеричный код верхнего регистра. Я знаю, почему он это делает - трюк DAA в сборке позволяет очень быстро преобразовывать числа в шестнадцатеричные цифры верхнего регистра. В z88dk, где эта функция также находится в сборке, необходима дополнительная инструкция для преобразования обратно в нижний регистр.
Двоичный код HTC - 9216 байт, sdcc - 7150 байт, а z88dk - 6604. Эти цифры не вполне справедливы для прямого сравнения. Sdcc только предоставляется простой putchar для печати на терминал cpm, но HTC и z88dk имеют реальную реализацию stdio для cpm. Я не знаю, создает ли HTC также буферы для ввода / вывода файлов, но z88dk - нет. Компиляция z88dk также уменьшает printf до «% x» только. Компиляция без этой прагмы приводит к размеру 7156 байт. В printty z88dk намного больше, чем в HTC или SDCC, так что сложно сравнивать бинарные размеры с различными printfs.
Это хороший ориентир для тестирования операций с битами. Спасибо, что обратили на это мое внимание. Я добавлю его в те тесты, которые я сейчас делаю.
I had no problem compiling aes256 with sdcc.
You can see how I did it here:
https://drive.google.com/file/d/0B6XhJJ33xpOWS2g1a2NEempzdHc/view?usp=sharing
sdcc/build.bat shows how I built the demo using sdcc and targeted cpm.
z88dk/build.bat shows how I built the demo using zsdcc and targeted cpm and the spectrum.
The original source code had some problems.
First, it's using K&R syntax for function parameters. I understand why he did that - most of the CP/M era compilers are not ansi and cannot do proper function syntax. K&R syntax was abandoned 30 years ago and sdcc has not got around to supporting it because it's not important. I fixed the parameter passing to be ansi.
Second, demo.c does not have function prototypes for functions exported from aes256.c. I suspect that the original author included aes256.c into demo.c and then compiled demo.c. This is because it's harder to do separate compilation on the old compilers. I added the missing function prototypes and used separate compilation for sdcc and z88dk. You can see why separate compilation is harder for these old compilers by looking at sdcc/make.bat -- it's also harder for sdcc. In z88dk/make.bat you just add another source file to the compile line.
If you look at the results, HTC v309 is not properly printing out the hex digits. %x is supposed to be lower case hex but HTC is ignoring this and just printing upper case hex. I know why it does this -- a DAA trick in assembly allows very fast conversion of numbers to upper case hex digits. In z88dk, where this function is also in assembly, an extra instruction is needed to convert back to lower case.
The HTC binary is 9216 bytes, sdcc is 7150 bytes and z88dk is 6604. These numbers are not quite fair for direct comparison. sdcc is only given a simple putchar to print to the cpm terminal but HTC and z88dk have a real stdio implementation for cpm. I don't know if HTC is also creating buffers for file i/o but z88dk is not. The z88dk compile is also reducing printf to "%x" only. A compile without this pragma results in 7156 bytes in size. z88dk's printf is much more complete that HTC's or SDCC's so again it's hard to directly compare binary sizes with varying printfs.
This is a good benchmark for testing bit operations. Thank you for bringing it to my attention - I will add it to the benchmarks I am currently doing.
Oleg N. Cher, я уже приводил в пример evo dsk с его примерами. после перехода на современную версию sdcc проекты перестают собираться или собираются в нерабочий код. если не веришь, проверь сам и попробуй собрать того же "game_xnx". Есть исходники других игрушек под атм написанных на этом sdk, они в версиях старше 2.9.0 не собираются.
Я посмотрю, смогу ли я найти это. Правда, есть некоторые ошибки в sdcc, особенно вокруг статики, но если вы не используете reserve-regs-iy, они не будут возникать так часто.
I will see if I can find this. It's true there are some bugs in sdcc especially around statics but if you don't use reserve-regs-iy, they won't come up quite as often.
Пиление на коленке никому не нужного uzix вместо того чтобы сделать, например, полезный баг-репорт в копилку SDCC
Гм... 100500 жутко пыльных топоров и пил стоят в ряд, один инструмент круче другого, да...
Но примостить пятую точку хочется именно на "никому не нужную" скамейку, а не на топор.
(Ушел)
OrionExt
28.03.2017, 17:49
Может не совсем по теме. Кстати кто ту писал, что на языках высокого уровня для Z80 не создано ни одного серьезного программного продукта в то время.
В свое время заинтересовался реверсом компилятора HTC 3.09. Так он как раз написан Си HTC.
Причем повторная сборка компилятора давала код в один в один как оригинал. К сожалению, пришлось оставить эту затею:( За неимение знаний в области компиляторов.
Oleg N. Cher
28.03.2017, 20:47
OrionExt, компилятор Hitech C не может быть написан на Си. Я скорее поверю, что он написан на PL/M.
Доказательства в студию. Хотя бы упоминание об этом хотя бы где-то. Дизассемблер, наконец. Честно, упаривает, когда распространяют ничем не обоснованные слухи.
- - - Добавлено - - -
Sayman, ну что ты про "переход с Hitech на sdcc вызывал проблемы". Ну и обратно - тоже будут проблемы. Удивил.
- - - Добавлено - - -
Ewgeny7, это uzix-то скамейка среди топоров? Смешно. Скорее уж TR-DOS тогда.
- - - Добавлено - - -
А что делать не многим любителем которые писали софт под 2,9?. Любитель перемен)Для этих любителей есть хороший совет - вынуть руки из жопы и перейти на свежую версию SDCC. И ещё. Иметь благодарность за то, что им предоставили пусть и неидеальный компилятор, но очень приличный, притом нахаляву. И совсем неплохо поучаствовать в развитии инструмента разработки, которым пользуешься.
Oleg N. Cher, я уже приводил в пример evo dsk с его примерами. после перехода на современную версию sdcc проекты перестают собираться или собираются в нерабочий код.
А мужики то не знают.
main.c:71: warning 158: overflow in implicit constant conversion
main.c:79: warning 158: overflow in implicit constant conversion
main.c:79: warning 158: overflow in implicit constant conversion
main.c:88: warning 158: overflow in implicit constant conversion
main.c:88: warning 158: overflow in implicit constant conversion
main.c:88: warning 158: overflow in implicit constant conversion
main.c:88: warning 158: overflow in implicit constant conversion
main.c:97: warning 158: overflow in implicit constant conversion
main.c:97: warning 158: overflow in implicit constant conversion
main.c:97: warning 158: overflow in implicit constant conversion
main.c:97: warning 158: overflow in implicit constant conversion
main.c:107: warning 158: overflow in implicit constant conversion
main.c:107: warning 158: overflow in implicit constant conversion
main.c:107: warning 158: overflow in implicit constant conversion
main.c:107: warning 158: overflow in implicit constant conversion
main.c:107: warning 158: overflow in implicit constant conversion
main.c:118: warning 158: overflow in implicit constant conversion
main.c:118: warning 158: overflow in implicit constant conversion
main.c:118: warning 158: overflow in implicit constant conversion
main.c:118: warning 158: overflow in implicit constant conversion
main.c:118: warning 158: overflow in implicit constant conversion
main.c:118: warning 158: overflow in implicit constant conversion
main.c:130: warning 158: overflow in implicit constant conversion
main.c:130: warning 158: overflow in implicit constant conversion
main.c:130: warning 158: overflow in implicit constant conversion
main.c:130: warning 158: overflow in implicit constant conversion
main.c:130: warning 158: overflow in implicit constant conversion
main.c:130: warning 158: overflow in implicit constant conversion
main.c:130: warning 158: overflow in implicit constant conversion
main.c:143: warning 158: overflow in implicit constant conversion
main.c:143: warning 158: overflow in implicit constant conversion
main.c:143: warning 158: overflow in implicit constant conversion
main.c:143: warning 158: overflow in implicit constant conversion
main.c:143: warning 158: overflow in implicit constant conversion
main.c:143: warning 158: overflow in implicit constant conversion
main.c:157: warning 158: overflow in implicit constant conversion
main.c:157: warning 158: overflow in implicit constant conversion
main.c:157: warning 158: overflow in implicit constant conversion
main.c:157: warning 158: overflow in implicit constant conversion
main.c:157: warning 158: overflow in implicit constant conversion
main.c:157: warning 158: overflow in implicit constant conversion
main.c:157: warning 158: overflow in implicit constant conversion
main.c:157: warning 158: overflow in implicit constant conversion
main.c:171: warning 158: overflow in implicit constant conversion
main.c:171: warning 158: overflow in implicit constant conversion
main.c:171: warning 158: overflow in implicit constant conversion
main.c:171: warning 158: overflow in implicit constant conversion
main.c:171: warning 158: overflow in implicit constant conversion
main.c:171: warning 158: overflow in implicit constant conversion
main.c:171: warning 158: overflow in implicit constant conversion
main.c:171: warning 158: overflow in implicit constant conversion
main.c:171: warning 158: overflow in implicit constant conversion
main.c:171: warning 158: overflow in implicit constant conversion
main.c:925: warning 196: pointer target lost const qualifier
Compiled code size 15730 bytes (56320 max, 40590 left)
35 RAM pages (560K) used:
Code: 12,13,14,15
Sprites buffer: 8,9,10,11
Graphics data: 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32 ,33,34,35
Palettes and params: 4
Sound code and sfx: 0
Music data: 36
Sample data: 37,38
Sprite data: 39
Sprite parameters: 660345
OrionExt
28.03.2017, 21:32
OrionExt, компилятор Hitech C не может быть написан на Си. Я скорее поверю, что он написан на PL/M.
Почему вы исключаете такую возможность в принципе?
Ваше право верить или не верить. Я, конечно, не могу утверждать, что в коде HTC 3.09 который таки написан на самом же HTC 3.хх нет ассемблерных вставок. Потому что работа была приостановлена. Почему HTC 3.хх? Мною были найдены не большие отличия в библиотеках, поставляемых с HTC 3.09.
Для этих любителей есть хороший совет - вынуть руки из жопы и перейти на свежую версию SDCC. И ещё.
Толсто.
Oleg N. Cher
28.03.2017, 22:37
Почему вы исключаете такую возможность в принципе?Интуитивно отвергаю, потому что я имею опыт работы с компиляторами, написанными на ЯВУ. И опыт работы с ЯВУ на Z80. Но хорошо, я, быть может, не совсем прав, потому что вопрос этот не для гадания, надо взять и узнать это точно.
Я верю Alcoholics Anonymous, когда он пишет про то, что в Hi-Tech C есть баги. Проверять, опять же, не проверял. У меня есть ещё желание собрать игру Dash с помощью Hi-Tech C v3.09. Почему именно Dash, а не другие игры? Потому что переносить библиотеки ZXDev с SDCC на Hi-Tech C это трудоёмкая и кропотливая работа. Это к вопросу о переводе проекта с одного компилятора на другой. Всегда трудоёмко. А Dash не использует библиотеки ZXDev.
Толсто.Зато правда.
Я встречаю два рода отношений к средствам разработки. Первый - потребительское отношение. Человек заинтересован в том, чтобы разрабатывать свой проект, и его злит и отвращает, когда он по вине средства разработки сталкивается с трудностями, когда средство сложное или работает по другому принципу, чем он привык и у него в голове сложилось. Дело может быть даже не в недостатках средства разработки, а просто в другой логике работы, непривычных решениях, к которым привыкать не хочется, а хочется по старинке. Я знаю оберонщиков, которые пишут на Обероне как на Дельфи, вплоть до названий классов и модулей.
Второй род отношений - это общее понимание как это должно быть устроено, что хорошо, что плохо, где можно упростить, а что является излишеством. Размышление идёт в контексте собственных исследований, которые помогают выстроить понимание средства и его недостатков. Человек исследует средство с чистого листа, не по аналогии, как проектировщик-железячник, старается смотреть на него с позиций гармонии. Тогда недостаткам ищутся объяснения, человек вкладывается в полюбившееся средство, тратит своё время на то, чтобы сделать его лучше. И такое отношение встречается гораздо реже.
Так вот, тут выступают за первый способ. Тогда Hi-Tech C можно рассматривать, если не смущают его баги, просто для ускорения работы, нежелания изучать другие, открытые компиляторы и вкладываться в их разработку. Но если смотреть на перспективу (я верю в будущее z88dk и SDCC, их разрабатывают КАЖДЫЙ ДЕНЬ), то Hi-Tech C не подходит, ведь он совсем не развивается. Так что из нас каждый по-своему прав, кто-то в нежелании переводить проект под другой компилятор, а кто-то из-за нежелания столкнуться с багами в закрытом компиляторе. Ну а мне ещё и фич SDCC в хайтехе не хватает...
OrionExt
29.03.2017, 00:25
Ну, вот нормальный ответ, без предвзятого отношения.
Так вот, тут выступают за первый способ.
И это не мудрено. Все держится на любителях. Коих большинство. И это отрицать глупо. Разбираться в чужом коде почему оно не работает, желания мало. Лучше это время потратить на свое творчество.
И опыт работы с ЯВУ на Z80. Но хорошо, я, быть может, не совсем прав, потому что вопрос этот не для гадания, надо взять и узнать это точно.
Фига тут узнавать. Вот листинг CGEN с IDA. С остальными программами из пакета HTC аналогичная ситуация.
В этом листинге при быстром рассмотрении мало чего понятно, хотя и при детальном тоже. Можно увидеть четко стандартный старт HTC для СР/М программы, функцию main, стандартные библиотеки HTC, характерные подпрограммы для HTC csv и cret захода и выхода из функции.
Мне вот интересно на чем шла разработка HTC на машине с Z80 или на какой-то более продвинутой машине.
- - - Добавлено - - -
Отреверсил функцию main на 80% с попаданием 98% в оригинальный код. А дальше для меня начался темный лес. И это не мудрено я до сих порт значок "*" путаю:)
- - - Добавлено - - -
Вся это работа была проделана просто из спортивного интереса. Если бы за это взялся профессионал, то возможно мы бы получили еще один компилятор Си. Таки у HTC есть потенциал, если его умудрились запихнуть в скромные рамки платформы на Z80.
А мужики то не знают.
и действительно, мужики-то и не знают:
http://zx-pk.ru/threads/18587-xonix-dlya-zx-evolution.html?p=483953&viewfull=1#post483953
http://zx-pk.ru/threads/20220-project-robo-novaya-igra-dlya-pent-evo.html?p=790095&viewfull=1#post790095
и твой же пост: http://zx-pk.ru/threads/6844-ishchu-si-dlya-z80.html?p=702277&viewfull=1#post702277
сейчас сам проверил на последней версии sdcc. xnx собрался, с матами и перематами, долго. Запускается, вроде даже надписи все на своих местах...
И вообще, как то люто ненавидит этот новый sdcc массивы без явного указания размера. Бред. Постоянные какие то "переполнения" у него. Да. Это прекрасный компилятор, очень и очень.:v2_wacko:
...
чё-то анреал какой-то. воткнул ключ --max-allocs-per-node200000 и пипец, он завис чтоли, этот sdcc? уже минут 10 чёто мухрюет там... ощущение. что я сижу на древней 286, а не на 8ми ядернике. это типо прикольно, таким компилятором пользоваться))))
Oleg N. Cher
29.03.2017, 16:03
Угу. В SDCC и ещё куча других недостатков, и о них можно писать целые толмуты. Однако же перед тем, как юзать 200000, поюзай меньшее число. Надо же знать логику этого, чтобы пользоваться грамотно. А массивы без указания размера моветон. Кстати, а хайтек как, хавает?
- - - Добавлено - - -
Я чего-то думаю, что SDCC сделает код получше хайтековского без всяких там --max-allocs-per-node
Филипп честно предупредил меня, что SDCC оптимизирован для использования на Win7 и выше. В XP, которой я до сих пор пользуюсь (старенький ноут на одноядерном проце + один из первых двухъядерных атлонов) компиляция в разы медленее. Тем не менее, жить можно.
Не буду развивать тему, что кто хочет найти недостатки - тот найдёт их всегда. Восприятие у чела такое, везде какашки видит, кроме своего любимого туалета.
OrionExt, компилятор Hitech C не может быть написан на Си. Я скорее поверю, что он написан на PL/M.
Доказательства в студию. Хотя бы упоминание об этом хотя бы где-то. Дизассемблер, наконец. Честно, упаривает, когда распространяют ничем не обоснованные слухи.
Мне нравятся такие категоричные утверждения
а загрузить и посмотреть вера не позволяет?
https://www.dropbox.com/s/ywa2fv8tagla0av/hisoft%20C.idb?dl=0
на, смотри адрес запуска #6270
люди так не пишут - а вот компилятор С вполне.
Alcoholics Anonymous
29.03.2017, 20:41
и действительно, мужики-то и не знают:
http://zx-pk.ru/threads/18587-xonix-dlya-zx-evolution.html?p=483953&viewfull=1#post483953
http://zx-pk.ru/threads/20220-project-robo-novaya-igra-dlya-pent-evo.html?p=790095&viewfull=1#post790095
и твой же пост: http://zx-pk.ru/threads/6844-ishchu-si-dlya-z80.html?p=702277&viewfull=1#post702277
сейчас сам проверил на последней версии sdcc. xnx собрался, с матами и перематами, долго. Запускается, вроде даже надписи все на своих местах...
И вообще, как то люто ненавидит этот новый sdcc массивы без явного указания размера. Бред.
Я нашел xnx-evo в последнем выпуске evo sdk.
У меня тоже не было проблем с компиляцией.
https://drive.google.com/file/d/0B6XhJJ33xpOWMVk1UDBVZ0xJREE/view?usp=sharing
В evo.h я прокомментировал некоторые прототипы:
I found xnx-evo in the latest evo sdk.
I didn't have any problems compiling it either.
https://drive.google.com/file/d/0B6XhJJ33xpOWMVk1UDBVZ0xJREE/view?usp=sharing
In evo.h I commented out some prototypes:
//заполнение памяти заданным значением
//void memset(void* m,u8 b,u16 len) _naked;
//копирование памяти, области не должны пересекаться
//void memcpy(void* d,void* s,u16 len) _naked;
//генерация 16-битного псевдослучайного числа
//u16 rand16(void) _naked;
//установка цвета бордюра, 0..15
Это имеет смысл в версии 2.9, но приведет к ухудшению кода в новых версиях sdcc. Причина: sdcc теперь попытается встроить несколько строковых функций, включая memset () и memcpy (). Если вы посмотрите на сгенерированный ASM с новой компиляцией, вы увидите, что эти вызовы функций реализованы с помощью ldir, встроенного в код. Определение ваших собственных функций для замены этого ухудшит ситуацию.
Я сделал то же самое для rand (). Я подозреваю, что это лучше реализовано в библиотеке компилятора, но я не проверял, чтобы реализация evo-sdk точно знала. Sdcc теперь использует генератор xars Marsaglia, который работает очень быстро, даже несмотря на то, что он реализован в C. В основном я это сделал, потому что z88dk реализует эту функцию в ASM.
В main.c я изменил некоторые заголовки:
This made sense in 2.9 but will result in worse code in newer versions of sdcc. The reason is sdcc will now try to inline several string functions including memset() and memcpy(). If you look at the generated ASM with a new compile you'll see these function calls implemented with ldir inlined in the code. Defining your own functions to replace this will make things worse.
I did the same for rand(). I suspect this is better implemented in the compiler's library but I did not check evo-sdk's implementation to know for sure. sdcc now uses a Marsaglia xor generator which is very fast even though it's implemented in C. Mainly I did it because z88dk implements this function in ASM..
In main.c I changed some of the header includes:
//#include <evo.h>
#include <string.h>
#include "evo.h"
Угловые скобки предназначены для заголовков, найденных в системном каталоге. Это не то, где evo.h находится в моих компиляциях, поэтому я изменил это на кавычки. Я также добавил string.h для получения библиотек memset () и memcpy ().
Я не могу скомпилировать бинарный файл, потому что мне придется исправлять остальную часть SDK, чтобы она была совместима с более новой версией sdcc. Но я могу перевести на asm и посмотреть, появляются ли какие-либо ошибки.
Angle brackets are for headers found in the system directory. That's not where evo.h is in my compiles so I changed that to quotes. I also added string.h to get the library memset() and memcpy() .
I can't compile to a binary because I'd have to fix up the rest of the SDK to be compatible with a newer version of sdcc. But I can translate to asm and see if any errors pop up.
sdcc -mz80 -S main.c -D_naked= (~1-2 minutes)
sdcc -mz80 -S --max-allocs-per-node200000 main.c -D_naked= (~14 minutes)
Вы можете выбрать, хотите ли вы быстро компилировать или оптимизировать. В этой программе не так уж много различий, потому что большинство переменных являются статическими. «-Dnaked =» заключается в том, чтобы устранить атрибуты «_naked» во всех функциях C в main.c. Вещи больше не делаются так в new sdcc.
Вы можете увидеть выходные файлы .asm в .zip выше. Беглый осмотр я не обнаружил.
You can choose if you want a fast compile or a highly optimized one. In this program there isn't too much difference because most variables are statics. The "-Dnaked=" is to eliminate the "_naked" attributes on all the C functions in main.c. Things are no longer done this way in new sdcc.
You can see the output .asm files in the .zip above. I did not spot any problems with a cursory examination.
Постоянные какие то "переполнения" у него. Да. Это прекрасный компилятор, очень и очень.:v2_wacko:
Это потому, что программист допустил ошибку или просто проигнорировал это. Компилятор правильный. Все эти жалобы касаются кода, подобного этому:
This is because the programmer has made a mistake or he's simply ignoring this. The compiler is correct. All those complaints are about code similar to this:
const u8 levelData1[]={
IMG_PIC1,PAL_PIC1,MUS_LOOP1,85,
9,10,-16,16,
28,10, 16,16,
255
};
Обратите внимание, что это массив символов UNSIGNED. Но программист ставит отрицательные числа там. Эти отрицательные числа представляют собой 16-разрядные целые числа. Например, -16 представляется как 0xffea. Затем компилятор пытается поместить 0xffea в 8-разрядный беззнаковый символ. Он делает все возможное, используя только младший байт и выдавая предупреждение, чтобы сообщить вам, что оно это сделало.
Поэтому все эти предупреждения являются ошибкой программиста. Sdcc прав, чтобы предупредить об этом - такие ошибки часто могут оказаться ошибками. В этом случае это не ошибки.
Немного позже в компиляции вы увидите еще одно предупреждение о потере указателя CONST. Это связано с тем, что программист неявно преобразовал указатель CONST в обычный указатель. Опять же, это предупреждение правильное, и оно испускается, потому что это еще один распространенный тип ошибки. Но в этом случае нет ошибки.
Начинающие могут найти предупреждения, сбивающие с толку или раздражающие, но для опытных они могут быть бесценными для отслеживания трудно найти ошибки. Тот факт, что другие компиляторы не могут сообщать обо всех этих вещах как о предупреждениях, является слабостью этих других компиляторов.
Я сделал ту же компиляцию с zsdcc, но на этот раз zsdcc будет использовать «-reserve-regs-iy», что подразумевается «-clib = sdcc_iy». В результирующем коде есть два места, где z88dk исправляет ошибки в sdcc. В z88dk предпочтительнее использовать «-reserve-regs-iy», потому что это приводит к значительно меньшему коду в целом, когда применяется агрессивный набор гласных z88dk.
Notice that this is an UNSIGNED char array. Yet the programmer is putting negative numbers in there. These negative numbers are 16-bit integers. For example, -16 is represented as 0xffea . The compiler then tries to fit 0xffea into an 8-bit unsigned char. It does its best by using only the least significant byte and emitting an warning to let you know it has done so.
So all those warnings are the fault of the programmer. sdcc is right to warn about it -- these types of errors can often turn out to be bugs. In this case these aren't bugs.
A little later in the compile you will see another warning about a pointer losing CONST. This is because the programmer has implicitly casted from a CONST pointer to a regular pointer. Again, this warning is correct and it is emitted because this is another common type of bug. But in this case there is no bug.
Beginners may find the warnings disconcerting or annoying but for the experienced they can be invaluable for tracking down difficult to find bugs. The fact that other compilers may not report these things as warnings is a weakness of those other compilers.
I did the same compile with zsdcc but this time zsdcc will use "--reserve-regs-iy" which is implied by "-clib=sdcc_iy". In the resulting code there are two places where z88dk fixes up bugs in sdcc. In z88dk it's preferable to use "--reserve-regs-iy" because it leads to much smaller code in general when z88dk's aggressive peephole set is applied.
zcc +z80 -vn -a -SO3 -clib=sdcc_iy main.c -D_naked= --c-code-in-asm (~1-2 minutes)
zcc +z80 -vn -a -SO3 -clib=sdcc_iy --max-allocs-per-node200000 main.c -D_naked= --c-code-in-asm (~16 minutes)
(Целевой компьютер «+ z80» не имеет большого значения для перевода в .asm. Это повлияет только на то, какие заголовки доступны из библиотеки).
(The target machine "+z80" does not matter much for a translation to .asm. It will only affect what headers are available from the library).
...
чё-то анреал какой-то. воткнул ключ --max-allocs-per-node200000 и пипец, он завис чтоли, этот sdcc? уже минут 10 чёто мухрюет там... ощущение. что я сижу на древней 286, а не на 8ми ядернике. это типо прикольно, таким компилятором пользоваться))))
Да, это медленно. Команда sdcc не рассматривала лучшие структуры данных в своей первой попытке с этим новым генератором кода. Имейте в виду, что то, что делает sdcc за кулисами, гораздо сложнее, чем, скажем, HTC.
Просто уменьшите число «max-allocs-per-node» или вообще исключите этот параметр (по умолчанию используется «max-allocs-per-node3000»). В этой программе это не имеет большого значения.
Я использую 200000 для релизов и когда я ищу способы улучшить вывод кода. Для меня вполне приемлема длинная сборка для выпуска. Для развития вы можете пойти ниже. Я не думаю, вместо этого я правильно разбиваю проект на множество исходных файлов и использую make-файл, так что только файлы, которые я изменяю, перекомпилируются. Таким образом, количество кода, который компилятор должен пережевывать, меньше и вывод генерируется быстрее.
Кстати, Philip at sdcc использует 1000000, когда он запускает тесты. Я не могу использовать этот номер на этом ноутбуке, так как для больших программ он будет исчерпан. Я также считаю, что разница не слишком велика между 200000 и 1000000. Из-за этого мы принимаем 200000 в качестве магического числа и фокусируем усилия на улучшении вывода кода для этого уровня. Я думаю, что Fuzix принял наш номер 200000 тоже, но в прежние времена это было 500000, я верю.
Yes it is slow. The sdcc team did not consider better data structures in their first attempt with this new code generator. Keep in mind that what sdcc is doing behind the scenes is much more sophisticated than what, say, HTC is doing.
Just reduce the "max-allocs-per-node" number or eliminate the option altogether ("max-allocs-per-node3000" is the default). In this program it doesn't make a huge difference.
I use 200000 for release builds and when I am looking for ways to improve the code output. A long build for a release is perfectly acceptable to me. For development you may want to go lower. I don't though, instead I properly partition a project into many source files and use a makefile so that only files I change are recompiled. This way the amount of code the compiler has to chew on is smaller and output is generated more quickly.
By the way Philip at sdcc uses 1000000 when he runs benchmarks. I can't use that number on this laptop as it will run out of memory for large programs. I also find the difference is not too much between 200000 and 1000000. Because of this we adopt 200000 as the magic number and focus efforts to improve code output for this level. I think Fuzix has adopted our 200000 number too but in earlier days it was 500000 I believe.
OrionExt
29.03.2017, 22:08
Компилятор Hi-Tech C v3.09 достаточно "простой" (пусть будет в кавычках). В этом я думаю его сила. Он не ищет в коде Си того, чего там нет. С другой стороны эта "простата" иногда вылазит боком в неэффективный код. Но, зная особенности компилятора и Z80, эти несуразицы можно свисти к минимуму. Чем, похоже, и пользовались авторы этого компилятора.
После недели втыкания в дизассемблер HTC 3.09 я уже мог на лету в голове получать си код. Вот загрузка n-го количества параметров в функцию, вот if then переход, а вот оператор case.
Если мне не изменяет память, HTC 3.09 создавался с выключенной оптимизацией. При включённой оптимизации мне не удавалась после рекомпиляции получить 98% оригинального кода.
Хотя не все там так просто. Похоже, использовались безусловные переходы, что не приветствуется. Натыкался на код, который я не смог раскусить (ассемблерная вставка?)
Все выше сказанное не принимайте за истину. Мне просто было интересно проделать кусочек этой работы и приоткрыть завесу тайны самого эффективного компилятора Си на платформе СР/М Z80:)
Alcoholics Anonymous
30.03.2017, 00:22
Компилятор Hi-Tech C v3.09 достаточно "простой" (пусть будет в кавычках). В этом я думаю его сила. Он не ищет в коде Си того, чего там нет. С другой стороны эта "простата" иногда вылазит боком в неэффективный код. Но, зная особенности компилятора и Z80, эти несуразицы можно свисти к минимуму. Чем, похоже, и пользовались авторы этого компилятора.
Результаты, которые получает HTC, очень впечатляют и вдвойне, если учесть, что он работает на 64-килобайтной машине. Как уже упоминалось в предыдущем посте, было бы целесообразным проект разобрать и понять этот компилятор с целью сделать его способным ориентироваться на машины z80 в целом. Отделите его от CP / M и подключите его к более общим и современным библиотекам, и там есть большой потенциал. Я думаю, любой, у кого есть реальная машина z80, с удовольствием сможет запустить такой компилятор на самой машине.
На самом деле, вы, вероятно, можете получить 80% пути к идеальной компиляции, не прибегая к мегабайтам интеллекта. Это последние 20%, которые нуждаются в большом анализе и обработке. Sdcc имеет большую часть этого процесса, но он еще далек от совершенства, поэтому вы будете иногда видеть, как он избивается в сравнении с «более простыми» компиляторами.
The results that HTC gets is very impressive and doubly so when considering it runs on a 64k machine. As was mentioned in a previous post, it would be a worthwhile project to disassemble and understand this compiler with the aim of making it able to target z80 machines generally. Detach it from CP/M and connect it to more general and modern libraries and there is a great a deal of potential there. I think anyone with a real z80 machine would love to be able to run such a compiler on the machine itself.
In reality, you can probably get 80% of the way to an ideal compile without resorting to megabytes of intelligence. It's the last 20% that needs a lot of analysis and processing. sdcc has the most of this going on but it is far from perfect yet so you'll occasionally see it getting beat in comparisons with "simpler" compilers.
Если мне не изменяет память, HTC 3.09 создавался с выключенной оптимизацией. При включённой оптимизации мне не удавалась после рекомпиляции получить 98% оригинального кода.
Я бы сделал то же самое, если бы работал в Hitech :) Существует больше шансов, что ошибки появятся с включенной оптимизацией, поэтому безопасным делом было бы скомпилировать компилятор с выключенной оптимизацией, если это так и было сделано.
I would have done the same if I worked at Hitech :) There is a greater chance for bugs to appear with the optimization enabled so the safe thing to do would be to compile the compiler with optimization off, if that's how they did it.
Oleg N. Cher
30.03.2017, 00:23
Да, примерно так же я декомпилировал игру, скомпилированную из Бейсика. Начинаешь улавливать, чего да как, появляется чутьё, где какая Бейсик-команда была. :-)
Если кому-то удастся реконструировать компилятор - конечно будет интересно.
да ковырять тут надо не столько сам компилятор, сколько его оптимизатор, файл optim.com. Вот его бы подправить и было бы хорошо, ещё лучше, наваять его под венду.
OrionExt
30.03.2017, 15:56
На самом деле, вы, вероятно, можете получить 80% пути к идеальной компиляции, не прибегая к мегабайтам интеллекта. Это последние 20%, которые нуждаются в большом анализе и обработке. Sdcc имеет большую часть этого процесса, но он еще далек от совершенства, поэтому вы будете иногда видеть, как он избивается в сравнении с «более простыми» компиляторами.
Поддерживаю на сто процентов.
Эта фраза подтолкнула меня продолжить любительские суждения о кодогенерации вокруг Z80.
Если пойти дальше и начать рассматривать такие продукты как НТС v7.80 pl2 и SDCC. Первое что я бы их "в лоб" не сравнивал. НТС v7.80 pl2 и SDCC преследовал / преследует разную конечную цель. Это главная мысль.
От этого и с заядлым постоянством вспыхивающий тут холивар. Чем тоже грешил. Потому что не правильно позиционировал компилятор для себя. Конечно проще написать ???? и сказать "фу какая хрень".
Вернемся к кодогенерации. Оба компилятора успешно подошли к планке 90% эффективности генерирования кода.
НТС v7.80 pl2 коммерческий продукт с конечным финансированием и в дальнейшем товар, от которого получали прибыль. Остановился в своем развитии. И достаточно стабильным и прогнозируемым генерируемым кодом на выходе. Сужу на основе разбираемого мною дизассемблера НТС 3.09 с отключенной оптимизацией (о оптимизации чуть позже). Это мой выбор.
SDCC исследовательский (научный) продукт с открытым кодом. Который преследует цель превысить 90% планку эффективности генерирования кода. И как показала не прекращаемая многолетняя работа над ним, постоянное шатание (отсюда не совместимость в версиях) и как тут было написано "прибегая к мегабайтам интеллекта" - пока с переменным успехом. А так современный компилятор вполне работоспособен при правильном подходе к нему. Что бы я отметил. Не подходит для новичков и у профессионалов с ним периодический происходят трудности в использовании.
По поводу эффективных и не эффективных библиотек и ловли блох у каждого из компиляторов. Ставить одну библиотеку над другой и определенные ходы в кодогенерации, думаю, не стоит. Все они преследуют определенные цели в узких рамках Z80.
Ага, оптимизатор. Новичкам я бы посоветовал его отключить. У меня на начальном освоении компилятора с ним возникли большие трудности, я долго не мог понять, что происходить и отчего так выборочно "плющит" генерируемый код. Оптимизатор может исказить сгенерированный код после кодогенератора до неузнаваемости.
Ну и не все с этими оптимизаторами так просто
Я бы сделал то же самое, если бы работал в Hitech :) Существует больше шансов, что ошибки появятся с включенной оптимизацией, поэтому безопасным делом было бы скомпилировать компилятор с выключенной оптимизацией, если это так и было сделано.
Я почти уверен, что НТС 3.09 ушел в релиз с выключенной оптимизацией. Надо только вспомнить, найти папку с проделанной работай и проверить. У кого "заряжены" инструменты может сделать это и сам.
Ух, выговорился:)
Oleg N. Cher
30.03.2017, 16:41
Я не совсем согласен, что SDCC не подходит для новичков. Чем больше сообщество - тем лучше продукт, как правило. Даже новички могут получить от его использования свою пользу при подходе первого рода. И даже новички могут улучшить компилятор, дав, например, баг-репорт при подходе второго рода.
- - - Добавлено - - -
Было бы интересно увидеть новичка, ковыряющегося с эмулятором CP/M или DosBox и Hi-Tech C. :-)
По сути же наверно один z88dk даёт хотя бы генерацию в tap. А для SDCC же надо освоить хотя бы hex2bin.
Впрочем, пускай новички прокачивают опыт, тоже хорошо. Правда, мы об абстрактных новичках, я что-то их деятельности не наблюдаю.
Alcoholics Anonymous
01.04.2017, 00:24
Вернемся к кодогенерации. Оба компилятора успешно подошли к планке 90% эффективности генерирования кода.
Я думаю, что это слишком великодушно :) Мой ручной код asm намного лучше, в 3 раза меньше и быстрее в сложных функциях. Частично причина заключается в том, что все эти компиляторы начинаются с препятствия - они уже решили, что локальные переменные будут в стеке, и они будут проиндексированы с индексным регистром. В очень небольших функциях, как sdcc, так и HTC могут покончить с этим. Это совершенно противоположное тому, что происходит, когда я пишу сборку от руки. Я начинаю с того, что не хочу использовать индексные регистры, если мне это не нужно. Это одно решение вносит большой вклад в разрыв между компиляторами и людьми при написании кода z80.
Учитывая ограничение стекового фрейма, производительность компилятора обычно не ужасна. Иногда я приятно удивлён кодом sdcc, который появляется в небольших плотных циклах с 8-битными величинами. Иногда я вижу нечто, что производит обратное впечатление: P Эти вещи я стараюсь исправить в пост-обработке. HTC более шаблонный и предсказуемый в своем поколении кода. Это редко будет действительно плохой код, но вы редко будете так что-то действительно умный. Когда я вижу вывод sdcc, ясно, что генератор кода z80 не рассматривает множество опций и не требует правильного использования индексных регистров (поэтому z88dk может получить намного лучший код из sdcc с помощью -reserve-regs- Iy "). Имейте в виду, что современный компилятор разделен между интерфейсом, в котором происходит весь анализ, и фоновым объектом, где лежит генератор кода. Это генератор кода, который, как я считаю, все еще имеет возможности для улучшения.
I think that is being much too generous :) My hand written asm code is much better, in the range of 3x smaller and faster in complex functions. Part of the reason is all these compilers begin with an impediment - they have already decided local variables will be on the stack and they will be indexed with an index register. In very small functions, both sdcc and HTC may do away with this. This is quite the opposite to what happens when I write assembly by hand. I begin by saying I don't want to use the index registers unless I really have to. That one decision contributes a great deal toward the gap between the compilers and humans when writing z80 code.
Given the stack frame constraint, the compiler performances are not usually terrible. Sometimes I am pleasantly surprised by code sdcc comes up with in small tight loops involving 8-bit quantities. Sometimes I see something that makes the opposite impression :P These things I try to fix up in post-processing. HTC is more formulaic and predictable in its code generation. It will rarely be really bad code but also you will rarely so something really clever. When I see sdcc's output, it's clear that the z80 code generator is not considering many options and doesn't cost the use of index registers properly (this is why z88dk can get much better code out of sdcc with "--reserve-regs-iy"). Keep in mind a modern compiler is divided between a front-end where all the analysis happens and a back-end where the code generator lies. It's the code generator that I believe still has room for improvement.
По поводу эффективных и не эффективных библиотек и ловли блох у каждого из компиляторов. Ставить одну библиотеку над другой и определенные ходы в кодогенерации, думаю, не стоит. Все они преследуют определенные цели в узких рамках Z80.
Компилятор C состоит из двух частей - переводчика языка и библиотеки. Оба одинаково важны, чтобы позволить программисту выполнить что-либо. Вы можете попробовать делать программы с GCC без GLIBC, но вы не очень далеко. Аналогично попытайтесь построить что-нибудь с помощью Visual Studio, не связывая время выполнения c microsoft или его код win32 gui. Библиотека является неотъемлемой частью компилятора, и поэтому стандарт C определяет, что должно быть там, как минимум. Если компиляторам не хватает больших порций, их полезность уменьшается.
На z80 библиотеки приобретают новое значение, поскольку компиляторы не могут генерировать почти такой же хороший код, как ассемблер, написанный руками.
Я могу показать вам результаты нескольких тестов, которые показывают, какой код библиотеки различий может сделать. Zsdcc будет использовать библиотеку языков ассемблера, а sdcc будет использовать свою собственную библиотеку, написанную на C. Имейте в виду, что zsdcc - это sdcc с некоторыми улучшениями, так что это почти сравнение равных.
A C compiler has two parts - the language translator and the library. Both are equally important to allow a programmer to accomplish anything. You can try to make programs with GCC without GLIBC but you won't get very far. Likewise try to build anything with Visual Studio without linking microsoft's c runtime or its win32 gui code. The library is an essential part of the compiler and that's why the C standard specifies what has to be in there at minimum. If compilers are missing large portions, their usefulness is decreased.
On the z80, the libraries take on a new importance because the compilers are not able to generate nearly as good code as hand written assembler.
I can show you a few benchmark results that demonstrate the difference library code can make. zsdcc will be using an assembly language library and sdcc will be using its own library written in C. Keep in mind zsdcc is sdcc with some improvements so this is almost a comparison of equals.
PI BENCHMARK (mainly testing 32-bit integer math)
Z88DK March 2, 2017
zsdcc #9833 / new c library / small int math
6246 bytes less page zero
cycle count = 5278798872
time @ 4MHz = 5278798872 / 4*10^6 = 22 min 00 sec
*****
SDCC 3.6.5 #9842 (MINGW64)
6844 bytes less page zero
cycle count = 8700157418
time @ 4MHz = 8700157418 / 4*10^6 = 36 min 15 sec
SDCC implements its 32-bit math in C.
Это на 63% медленнее, а дополнительные 600 байтов исходят из того факта, что 32-битная математика sdcc написана на C.
Если мы сможем принять большой размер кода, zsdcc может быть скомпилирован с использованием библиотеки с быстрыми целыми числами:
That's 63% slower and an extra 600 bytes coming from the fact sdcc's 32-bit math is written in C.
If we can accept a large code size, zsdcc can be compiled using a fast integer library:
Z88DK March 2, 2017
zsdcc #9833 / new c library / fast int math
8997 bytes less page zero
cycle count = 1739403552
time @ 4MHz = 1739403552 / 4*10^6 = 7 min 15 sec
Это теперь в пять раз быстрее, чем sdcc. И снова основное различие - библиотека.
Еще один большой результат - математика с плавающей запятой. Это из ЭТАПЫ WHETSTONE:
That's now five times faster than sdcc. Again the main difference is the library.
Another large result is in floating point math. This is from the WHETSTONE BENCHMARK:
Z88DK March 2, 2017
zsdcc #9833 / new c library / math48 float package
24 bit mantissa + 8 bit exponent (internally 40+8)
6153 bytes less page zero
cycle count = 916537242
time @ 4MHz = 916537242 / 4x10^6 = 229.1343 seconds
KWIPS = 100*10*1 / 229.1343 = 4.3643
MWIPS = 4.3643 / 1000 = 0.0043643
*****
SDCC 3.6.5 #9842 (MINGW64)
24 bit mantissa + 8 bit exponent
14379 bytes less page zero
cycle count = 2184812093
time @ 4MHz = 2184812093 / 4x10^6 = 546.2030 seconds
KWIPS = 100*10*1 / 546.2030 = 1.8308
MWIPS = 1.8308 / 1000 = 0.0018308
SDCC implements its float library in C.
Sdcc более чем в два раза медленнее с плавающей библиотекой, написанной на C (и посмотрите на разницу в размерах). Это намного хуже, чем то, что появляется на поверхности. В z88dk математическая библиотека внутренне реализует 48-битное число с плавающей точкой с 40-битной мантиссой. Библиотека sdcc должна иметь дело только с 32-битным плавающей точкой и 24-битной мантиссой. Это значительное преимущество в производительности. Плавающая библиотека sdcc должна иметь более чем у z88dk. На самом деле цифры должны быть наоборот.
Эти два теста показывают очевидную разницу, поскольку большая часть времени выполнения находится в коде библиотеки, а не в коде, генерируемом компилятором. В большинстве программ время выполнения будет не столько доминировать с помощью библиотечного кода, сколько преимущество в производительности библиотеки.
По крайней мере, столь же важным, как скорость выполнения, является размер программы. В больших программах существуют очень большие различия в размере кода между sdcc и zsdcc. Частью этого является улучшение генерации кода (улучшение размера кода на 5-10%, хотя есть случаи с краями до 50%), но большая часть кода библиотеки. Я видел экономию 10 тыс. И более на больших скомпилированных программах, главным образом из-за различий в размере кода библиотеки. В программе размер, HTC и другие, как правило, избивают SDCC. И снова это обычно сводится к размеру кода библиотеки. У HTC и других есть свод библиотечного кода, реализованного в ассемблере, тогда как sdcc имеет очень мало этого. В этих сравнениях z88dk также выигрывает у HTC и других в размере кода, в значительной степени благодаря тому, что z88dk имеет намного больший объем библиотечного кода, написанного на ассемблере.
Постобработка кода не вносит такой же вклад в экономию средств. Я считаю, около 5-10% размера является типичным. Воздействие на время выполнения может быть больше, если преобразования происходят внутри циклов. Одной из важных функций этих преобразований является исправление некоторых ошибок генерации кода sdcc, что позволяет нам надежно использовать «-reserve-regs-iy» и получать улучшенную генерацию кода из самого sdcc.
sdcc is more than twice as slow with a float library written in C (and look at the size difference). It's much worse than what appears on the surface. In z88dk, the math library internally implements a 48-bit float with a 40-bit mantissa. sdcc's library only has to deal with a 32-bit float and a 24-bit mantissa. That's a significant performance advantage sdcc's float library should have over z88dk's. In fact the numbers should be the other way around.
These two benchmarks show an obvious difference because most of the running time is in the library code rather than the compiler-generated code. In most code, execution time won't be dominated so much by library code but this library performance advantage will penetrate everywhere.
At least as important as the execution speed is the program size. In large programs there are very big differences in code size between sdcc and zsdcc. Part of it is better code generation (~5-10% code size improvement although there are fringe cases up to 50%) but a larger part is the library code. I have seen savings of 10k or more on large compiled programs mainly due to differences in library code size. In program size, HTC and others tend to beat sdcc as well. And again this is usually down to library code size. HTC and others do have a body of library code implemented in assembler whereas sdcc has very little of this. In these comparisons, z88dk also beats HTC and others in code size due in large part to the fact z88dk has a much larger body of library code written in assembler.
The post-processing of code doesn't contribute as much to savings. I find around 5-10% size is typical. The impact on running time can be larger if the transformations happen inside loops. One important function of these transformations is to fix some of sdcc's code generation bugs that allows us to reliably use "--reserve-regs-iy" and get improved code generation out of sdcc itself.
SDCC...Что бы я отметил. Не подходит для новичков и у профессионалов с ним периодический происходят трудности в использовании.
Я не уверен, что я полностью согласен с этим. Его проще использовать в том смысле, что он лучше соответствует стандартам и может компилировать больше программ, чем другие компиляторы z80. Запуск на современной машине, а не, скажем, CP / M отнимает искусственные ограничения на размер программы.
По сравнению с HTC и IAR, чего ему действительно не хватает, это несколько стандартных crts. Я видел, что многие люди борются с этим просто потому, что они не знали, как писать crt. После компиляции у вас есть .ihx-файл, который легко превратить в двоичный файл с помощью HEX2BIN. Кроме этого, я бы оценил его равным в простоте использования с IAR и HTC 309 (без учета ограничений, введенных CPM). У HTC 750 есть простая IDE, которая может понравиться некоторым пользователям, но я нахожу только отягчающей.
Z88DK имеет преимущества перед всеми этими компиляторами: - передний интерфейс позволяет легко смешивать c, asm, макросы и т. Д. Он может хранить отдельные библиотеки для любой машины z80 с выделением из строки компиляции. Крошки уже сделаны. Постобработка включает в себя шаг с использованием «APPMAKE», который может превращать выходные двоичные файлы в COM, ROM, TAP, DSK, независимо от цели. Одна строка для компиляции любого количества исходных файлов в требуемую форму вывода, и для экспертов есть много вариантов. ZSDCC работает внутри этой инструментальной цепи, поэтому «SDCC» также можно использовать в этом простом режиме.
I'm not sure I'd wholly agree with that. It's easier to use in the sense it has better standards conformance and can compile more programs than the other z80 compilers. Running on a modern machine instead of, say, CP/M takes away artificial limits on program size.
In comparison with HTC and IAR what it is really lacking is a few more standard crts. I've seen many people struggle with it simply because they did not know how to write a crt. After a compile you have an .ihx file which is easy to turn into a binary with HEX2BIN. Other than that I'd rate it equal in ease of use with IAR and HTC 309 (ignoring the limits introduced by CPM). HTC 750 has a simple IDE that some may like but I only find aggravating to use.
Z88DK has usage advantages over all these compilers :- the front end makes it easy to mix c, asm, macros, etc. It can hold separate libraries for any z80 machine with selection from the compile line. The crts are already made. The post processing involves a step using "APPMAKE" that can turn the output binaries into COM, ROM, TAP, DSK, whatever the target needs. One line to compile any number of source files to the required output form and there's a lot of options in between for experts. ZSDCC runs inside this toolchain so "SDCC" can be used in this easy manner too.
Oleg N. Cher
01.04.2017, 01:20
Alcoholics Anonymous, Ваши сообщения на форуме всегда очень подробны и интересны. Благодарю!
OrionExt
01.04.2017, 15:51
Alcoholics Anonymous, cпасибо. Очень полезные посты для понимания нюансов построения компиляторов для Z80.
- - - Добавлено - - -
z88dk уникальный проект, который рассчитан именно на Z80 платформу.
где бы раскопать процедурку printf? Получается .AS без печати.
Сижу, такой, дома, из-за этой псевдопандемии. перечитываю старые темы. наткнулся на эту. Хотелось бы прокомментировать пару моментов:
В evo.h я прокомментировал некоторые прототипы:
комментировать прототипы в SDK, в котором не используются стандартные библиотеки и заголовочные файлы, очень спорное действие. Все прототипы вами отключенные были полностью переписаны автором этого sdk. Например, memset(), в отличии от оригинального из библиотеки sdcc и других компиляторов делает вызов _FAST_LDIR, который в свою очередь:
;более быстрая версия ldir, эффективна при bc>12
;из статьи на MSX Assembly Page
;в отличие от нормального ldir портит A и флаги
_fast_ldir
xor a
sub c
and 63
add a,a
ld (.jump),a
.jump=$+1
jr nz,.loop
.loop
dup 64
ldi
edup
jp pe,.loop
ret
Т.е. вы пишите, что "эти вызовы функций реализованы с помощью ldir, встроенного в код. Определение ваших собственных функций для замены этого ухудшит ситуацию." не вникнув в суть кода, а суть в том, что обычный ldir это 21 такт на байт, а реализация memset в sdk при BC>12 даёт около 19 тактов и менее (если не ошибаюсь, вплоть до 17 или 18 тактов на байт). таким образом memset из sdk наоборот - повышает производительность. весь sdk написан без использования (стоковых библиотек, за исключением некоторых функций, который обязательны при кодогенерации.
Обратите внимание, что это массив символов UNSIGNED.
во1х, это массив без объявления размера. во2х, 8ми битный (не 16). число отрицательное, 8ми битное, в HEX это будет 0xf0. в одном из своих постов я приводил в пример высказывание автора игры Robo: " нужно было явно задать размеры массивов mus_cnt и musnames.". Т.е. проблема - если массив без размера, то ошибка компиляции. При этом всё тот же Hi Tech съедает эти массивы и даже не давится и код работает. Размер массива можно подсчитать в момент компиляции исходя из его наполнения. Почему-то sdcc после версии 2.9.0 резко разучился это делать. кроме этого, сам же автор игры пишет: "бинарный код под этой версией SDCC получился слишком большой. Игра компилируется, но не работает.". Я тоже пробовал собирать на разных версиях sdcc, но какие-то проблемы постоянно всплывают. при последней попытке я даже не дождался конца компиляции и это на amd ryzen 5 1600x разогнанном. у меня тут эмулятор zxmak2 в visual studio собирается за 3 секунды, какая-то спектрум игра за пол часа не собралась.
далее тоже интересно (про кодогенерацию sdcc): https://www.msx.org/forum/msx-talk/development/about-c-z80-optimizations-sdcc?page=5
look at vrampoke & vrampeek functions. SDCC generate some kind of lengtly code:
this segment
ld c, 1 (iy)
ld b, #0x00
ld a, c
and a, #0x3f
or a, #0x40
out (_port99), a
is simply extremely stupid.
ld c, then ld b, 00 then ld a, c (so first ld c could be ld a, .....
там есть и другие весьма детские болячки, которые просто годами не правятся.
хотя конечно, иногда пользуюсь этим компилятором (sdcc), но без фанатизма.
Столкнулся с проблемой. Линкер иногда (?) не находит в библиотеке метки, которые используются из других модулей.
Например, имеется модуль, в котором определена метка "udiv":
psect text
global udiv
udiv:
...
В другом модуле имеется обращение к этой метке:
psect text
global _foo
_foo:
...
call udiv
...
Если мы используем в си-исходнике функцию "foo":
foo();
то линкер запихнёт в выходной файл функцию "foo", но "udiv" не найдёт и вместо её адреса подставит в call нули.
Хотя модуль такой есть в библиотеке, и метка "udiv" как глобальная определена.
Кто-нибудь знает, как это побороть? А то, в общем-то, это ставит крест на компиляторе. Хотя на MSX его во всю юзают, и таких проблем, похоже, не испытывают.
Для работы использую cpm.exe из командной строки под Win10-64.
cpm.exe link.com -I -Z ...
Barmaley_m
19.06.2023, 00:09
компиляторы начинаются с препятствия - они уже решили, что локальные переменные будут в стеке, и они будут проиндексированы с индексным регистром.
Вот это, кстати, интересный момент.
Немногие задумывались, почему большинство компиляторов (в том числе для x86 или ARM) размещают локальные переменные в стеке.
А дело здесь в рекурсии. В языке C разрешена рекурсия - и поэтому компилятор исходит из того, что любая функция может быть рекурсивной. А для рекурсивных функций иного выхода и нет, кроме как организовать стек для хранения локальных переменных.
Иногда компилятор может доказать, что та или иная функция не вызывает сама себя - ни прямо, ни через другие функции. Для таких функций он может отказаться от использования стека, а для прочих - нет. Вызов функции по указателю - это один из случаев, когда компилятор всегда должен подразумевать возможную рекурсию, ведь он не знает, что будет вызвано. Будет ли код, вызывающий функцию по указателю, вызван впоследствии рекурсивно.
В этом смысле более эффективен Фортран, где рекурсия запрещена, и компиляторы имеют полную свободу оптимизации.
Рекурсия иногда нужна, поэтому лучшим решением я бы считал введение атрибутов для функций, которые программист не собирается вызывать рекурсивно. Аналогично тому, как в GCC можно задать функциям атрибут, что они никогда не возвращаются.
Lethargeek
19.06.2023, 19:59
А дело здесь в рекурсии.
в повторной входимости (что касается не только рекурсии)
Barmaley_m
20.06.2023, 01:03
в повторной входимости (что касается не только рекурсии)
А чем повторная входимость отличается от рекурсии?
NEO SPECTRUMAN
20.06.2023, 03:38
А чем повторная входимость отличается от рекурсии?
наверно рекурсия более узкое понятие
а повторная входимоссть может быть и без рекурсии
например функция вызываетсо несколькими потоками "одновременно"
- - - Добавлено - - -
Рекурсия иногда нужна, поэтому лучшим решением я бы считал введение атрибутов для функций, которые программист не собирается вызывать
именно поэтому сяпаскали ущербное гуавно
по дефолту прибито гвоздями то
что обычно никогда не надо
а то чего надо в упор нету....
как в GCC можно задать функциям атрибут, что они никогда не возвращаются.
а нахрена нужны "особые" атрибуты для такой функции?
как в проге может быть много не возвращаемых функций?
чтоб этот атрибут на что то влиял
в моем понимании невозвращаемая функция это типа mainloop-а
и не представяю зачем их нужно больше чем100500 в проге
это скорей затычка от детектора ошибки невозвращаемой функции
Barmaley_m
20.06.2023, 22:45
именно поэтому сяпаскали ущербное гуавно
по дефолту прибито гвоздями то
что обычно никогда не надо
а то чего надо в упор нету....
Это смотря чем ты занимаешься и какие есть альтернативы. Мне вот в настоящее время для решаемых задач Си подходит больше известных альтернатив. Но может, я чего-то не знаю. Какие бы ты предложил альтернативы Си?
а нахрена нужны "особые" атрибуты для такой функции?
Например, чтобы компилятор сэкономил немного на стеке и коде вызова и возврата из таких функций. Вызов заменяется безусловным переходом, регистры восстанавливать не надо.
как в проге может быть много не возвращаемых функций?
В моих проектах около десятка обычно встречается. Это, во-первых, стартовая функция каждого потока (во встраиваемых проектах потоки обычно не завершаются). Во-вторых это всякие функции сброса, перехода в загрузчик и т.п.
чтоб этот атрибут на что то влиял
В МК-проектах часто не хватает оперативы. В стеке каждого потока сэкономить десяток байт - уже где-то в другом месте становится легче дышать.
Экономия невелика, согласен. Но в других местах выжимать ресурсы бывает иногда еще труднее. Раз кто-то сделал в компиляторе этот атрибут - то пользуюсь при случае.
NEO SPECTRUMAN
21.06.2023, 04:23
Какие бы ты предложил альтернативы Си?
вот как раз несмотря на...
лично я альтернатив не знаю...
приходитсо пользоватсо тем что есть
и тем что повсеместно применимо и документировано
(и пушо никто не хочет писать/бекпортить\фиксить нужные мне софты а так я признаю ТОЛЬКО АСМ ибо в ЯВУ нельзя элеметарнейших вещей)
ясно одно
что пейсатели сей
не хотели и пальцем шевелить вставляя ЧУЖОЙ код к себе....
и что для спехтрума он не применим в принципе...
...на новые супер Языки Высокой Унылости
которых нынче развелось как грибов
и которые "лучше знают" как надо обращатсо к раме и защищают вашы банковские счета
я смотрю соответственно...
кстате паскали вне дельфи еще существуют?
там алоний чесал про какуето значимость паскалей в этой стране
а я ни одного компилятора новее 92 года и вспомнить не могу
Экономия невелика,
просто на фоне общей прожорливости
экономия байтов выглядит странно
Powered by vBulletin® Version 4.2.5 Copyright © 2026 vBulletin Solutions, Inc. All rights reserved. Перевод: zCarot