Enterprise Forever

:HUN => Programozás => Topic started by: Lacika on 2015.December.20. 08:55:41

Title: C programozás (Aztec C / Hisoft C)
Post by: Lacika on 2015.December.20. 08:55:41
Tud segíteni valaki C-ben?
Most ismerkedek vele mérsékelt sikerrel....

Két kérdésem lennem első körben az alábbi két programmal kapcsolatban: miért nem adnak helyes eredményt?
Az első egy sima gyökvonás:

main()
{
  int c;
  c=2;
  printf("%f",sqrt((double)c));
}

a második az adott implementáció szóhosszúságát adná meg:

wordlength()
{
  int i;
  unsigned v=~0;
  for(i=1; (v=v>>1)>0; i++) ;
  return(i);
}

main()
{
  printf("%d\n",wordlength);
}
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: IstvanV on 2015.December.20. 09:39:08
Ez működik PC-n GCC-vel fordítva, EP-s fordítót nem próbáltam (az include hiánya probléma lehetett, implicit deklarációval a visszatérési érték típusa int):
Code: C
  1. #include <stdio.h>
  2. #include <math.h>
  3. int main(void)
  4. {
  5.   int c;
  6.   c=2;
  7.   printf("%f\n",sqrt((double)c));
  8.   return 0;
  9. }

A második program javítva (a wordlength helyett wordlength(), az előbbi a függvény címe):

Code: C
  1. #include <stdio.h>
  2. int wordlength(void)
  3. {
  4.   int i;
  5.   unsigned v=~0;
  6.   for(i=1; (v=v>>1)>0; i++) ;
  7.   return(i);
  8. }
  9.  
  10. int main(void)
  11. {
  12.   printf("%d\n",wordlength());
  13.   return 0;
  14. }
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: Mayer Gábor on 2015.December.20. 10:30:45
Ilyet még talán nem is láttam, hogy unsigned magában. Ez ilyenkor unsigned int lesz ugye?

Nekem az lenne a kérdésem, bár lehet, hogy ep-t nem érinti, miért kell linuxon de lehet, hogy máshol is hozzá linkelni az alábbiakat a programhoz:

crt1.o
crti.o
crtbegin.o
crtend.o
crtn.o

Melyik micsoda és honnan jönnek ezek? Úgy értem a linuxnak muszáj vagy ez a gcc működéséből fakad és lehet, hogy más fordító nem tenné ezeket oda?

Title: Re: C programozás (Aztec C / Hisoft C)
Post by: IstvanV on 2015.December.20. 10:48:06
Ilyet még talán nem is láttam, hogy unsigned magában. Ez ilyenkor unsigned int lesz ugye?

Igen.

Quote
Melyik micsoda és honnan jönnek ezek? Úgy értem a linuxnak muszáj vagy ez a gcc működéséből fakad és lehet, hogy más fordító nem tenné ezeket oda?

A GCC automatikusan linkeli ezeket, ezért a fordításhoz elég az alábbi parancsokat használni:

gcc -Wall -O2 sqrt.c -o sqrt -lm
gcc -Wall -O2 wrdlngth.c -o wrdlngth

Ugyanez működik például az itt (https://enterpriseforever.com/ep128emu/ep128emu/msg31713/#msg31713) található Windows-os fordítóval is. HISOFT C-vel egyelőre nem sikerült lefordítani. :oops:
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: Mayer Gábor on 2015.December.20. 10:57:53
Ha tudjátok hogy mit csinálnak ezek az objectek az érdekelne.
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: Lacika on 2015.December.20. 11:05:52
Ep-n két használható fordítót találtam (kint vannak nálam):

Hisoft-C 1.33 : egyszerű, gyors fordító, de nem ismeri sem a float, sem a double tpust(!) Csak egész számokkal dolgozik... :( Nem egészen világos, mi a különbség a .H és a .LIB kiterjesztésű file között?

Aztec-C: ez macerásabb, 3-lépésben (!) kell fordítani (BAT-ot célszerű hozzá csinálni...). Itt az utolsó lépésben kell hozzálinkelni a programhoz az M.LIB (matematikai könyvtár) - ha lebegőpontos számokat is használunk, és a C.LIB-et. Ezért nincs a gyökvonásos programban include. A program hibamentesen lefordul, futtatásor mégis hibás eredményt ad.
Ezt a letölthető csomagot átnézné valaki, melyik file micsoda? :oops:
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: Lacika on 2015.December.20. 11:06:32
Ha tudjátok hogy mit csinálnak ezek az objectek az érdekelne.

Engem is. Bár én Ep-specifikus nézőpontból közelítek a kérdéshez. :ds_icon_cheesygrin:
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: Lacika on 2015.December.20. 11:08:26
Ilyet még talán nem is láttam, hogy unsigned magában. Ez ilyenkor unsigned int lesz ugye?

Itt már tartok. Erről konkrétan van említés itt (http://ep128.hu/Ep_Konyv/C_Programozasi_nyelv.htm).
Még kezdeti stádiumban van. Bármilyen észrevételt szívesen fogadok!
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: ergoGnomik on 2015.December.20. 12:48:43
Ilyet még talán nem is láttam, hogy unsigned magában. Ez ilyenkor unsigned int lesz ugye?

Nekem az lenne a kérdésem, bár lehet, hogy ep-t nem érinti, miért kell linuxon de lehet, hogy máshol is hozzá linkelni az alábbiakat a programhoz:

crt1.o
crti.o
crtbegin.o
crtend.o
crtn.o

Melyik micsoda és honnan jönnek ezek? Úgy értem a linuxnak muszáj vagy ez a gcc működéséből fakad és lehet, hogy más fordító nem tenné ezeket oda?
Keress leírásokat a C Runtime Library (magyarul C futásidejű könyvtár - talán) témakörben. Ezek alapvető szolgáltatásokat biztosítanak, ami lehetővé teszi a programnak az operációs rendszeren futtatását.
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: IstvanV on 2015.December.21. 14:42:13
PC-ről Z80-ra fordító programokkal is lehet próbálkozni, ha érdekel valakit ez a téma. A z88dk támogatja az EP-t és az EXOS 5-ös fejlécű formátumát (egy kisebb bug javítása után), ezért viszonylag egyszerű a használata. Az SDCC nehézkesebb, és úgy látszik, az EP támogatást külön meg kell valósítani hozzá, de jobb minőségű Z80 kódot generál, mint a z88dk.

Egy minimális példa program SDCC-vel fordítva:
[attachurl=1]
[attachurl=2]

sdcc -mz80 --code-loc 0x0180 --data-loc 0x4000 --stack-loc 0xf800 test.c
ihx2ep test.ihx loader.bin test.com


Az EP-s betöltő készítéséhez használt forráskódok:
[attachurl=3]
[attachurl=4]
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: IstvanV on 2015.December.21. 20:00:18
Továbbfejlesztett loader.s, amely megnyit egy EDITOR: csatornát 40x24 karakteres szöveges módban, és megvalósítja a karakter kiírást (így már működik a printf()):

[attachurl=1]
[attachurl=2]

1 és 10 közötti egészek négyzetgyökének a kiírása (az SDCC-s printf() nem támogatja a float típust, így ehhez külön rutint kellett írni):

[attachurl=3]
[attachurl=4]

[attachurl=5]
[attachurl=6]

gcc -Wall -O2 ihx2ep.c -o ihx2ep
sjasm loader.s loader.bin

sdcc -mz80 --code-loc 0x0200 --data-loc 0x4000 --stack-loc 0xf800 sqrt.c
ihx2ep sqrt.ihx loader.bin sqrt.com
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: Zozosoft on 2015.December.21. 22:01:45
Na most lehet, hogy nagy hülyeséget kérdezek :oops:
Ezek a modern PC-s Z80 C-k tudnak kezelni többet mint 64K?
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: IstvanV on 2015.December.21. 22:08:54
Na most lehet, hogy nagy hülyeséget kérdezek :oops:
Ezek a modern PC-s Z80 C-k tudnak kezelni többet mint 64K?

Mivel az EP-t csak korlátozottan támogatják, valószínűleg nem tudnak automatikusan lefoglalni és lapozni több memóriát. Ezt a programnak kellene megoldania asm rutinok beépítésével.
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: Zozosoft on 2015.December.21. 22:53:25
Ez nyilvánvaló :-) De úgy általában tudnak-e Z80-on lapozva sok memóriát kezelni? Amihez nyilván kellene a megfelelő szabványosan hívható assembly rutinokat elkészíteni.
Ahogy pl a printf-nek is előkészítetted a terepet.
De ha megvannak a lapozó rutinok, onnantól el lehetne feledni a 64K korlátot? Itt van pl Endi editorának az esete, ahol BASIC-ben elérte az egyszerre kezelhető memória határát, ez egy ilyen modern C-vel elkerülhető lenne?
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: lgb on 2015.December.21. 23:09:03
Az a baj, hogy a C filozofiajaban, ha mindent ki akarsz hasznalni akkor alapvetoen a mutato (pointer) fogalma fog betegeskedni. Marmint, egy 16 bites ertek mint pointer problema. Am, ha 64K-t tul akarod lepni akkor kellene olyan pointer, ahol mondjuk szegmensszam stb van. Ehhez viszont ugye lapozgatas stb kell allandoan, nem tul hatekony. Ugyan C-vel en inkabb mar "flat cimzesu" rendszereken talalkoztam mar (ahol ez nem problema), remlik, hogy meg DOS-os idokben is volt C compiler ahol emiatt kulonbozo tipusu mutatok is voltak, am ez mas kerdeseket is felvethet. Szerintem inkabb azt kene megvizsgalni, hogy valoban szukseg van-e arra, hogy minden mukodjon 64K-s hatart attorve, vagy elfogadhato, ha adott esetben platform specifikus dolgok vannak, akar pl ugy, hogy a megfelelo C fuggvenynek valo entitassal az ember lapozgat, mintha asm lenne a dolog. Nem tul szep, az igaz. Am a telejesen generic implementaciohoz az kene, hogy maga a core compiler (sdcc) tudjon errol (nem tudom ez mennyire lenne bonyolult), az mar nem csak annyi, hogy irunk loader-t meg miegymast hozza, amit ugye egy masik topic-ban regebben en is csinalgattam egy darabig (csak eppen akkoriban volt egy kis gond az sdcc-vel ami nagyon elvette a kedvemet tole, le is adtam nekik hibara).
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: IstvanV on 2015.December.21. 23:49:01
z88dk és SDCC összehasonlítása:

[attachurl=1]    (z88dk)
[attachurl=2]

[attachurl=3]
[attachurl=4]

zcc.exe +enterprise -lm -create-app -O3 -DFASTMATH -omandel_2 mandel_z88dk.c
zcc.exe +enterprise -lm -create-app -O3 -DFASTMATH -otunnel_2 tunnel_z88dk.c


[attachurl=5]    (SDCC)
[attachurl=6]

[attachurl=7]
[attachurl=8]
[attachurl=9]
[attachurl=10]

sdcc.exe -mz80 --code-loc 0x0200 --data-loc 0x4000 --stack-loc 0xf800 --opt-code-speed mandel.c
ihx2ep mandel.ihx loader.bin mandel.com
sdcc.exe -mz80 --code-loc 0x0200 --data-loc 0x4000 --stack-loc 0xf800 --opt-code-speed tunnel.c
ihx2ep tunnel.ihx loader.bin tunnel.com
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: IstvanV on 2015.December.22. 11:24:58
A fenti példák a gyakorlatban elsősorban a lebegőpontos rutinokat tesztelik, de az SDCC ezeknél meglepően lassú (a tunnel.com például csak kétszer gyorsabb, mint az IS-BASIC verzió, és a BASIC nagyobb pontosságú float típust használ). Lehet azonban, hogy a program írásánál vagy a fordításnál valamit nem jól oldottam meg. :oops:

Az alábbi egyszerű egész típuson végzett műveleteket tesztelő példát
Code: C
  1. int foo(int bar, int baz)
  2. {
  3.   int     i = 0;
  4.   while (baz < bar) {
  5.     baz = baz + (baz >> 3);
  6.     i++;
  7.   }
  8.   return i;
  9. }
így fordítja az SDCC (--opt-code-speed, --opt-code-size esetén a jobbra léptetést ciklussal oldja meg):
Code: ZiLOG Z80 Assembler
  1. _foo::
  2. ;c_test.c:5: while (baz < bar) {
  3.         ld      de,#0x0000
  4. 00101$:
  5.         ld      hl,#2
  6.         add     hl,sp
  7.         ld      iy,#4
  8.         add     iy,sp
  9.         ld      a,0 (iy)
  10.         sub     a, (hl)
  11.         ld      a,1 (iy)
  12.         inc     hl
  13.         sbc     a, (hl)
  14.         jp      PO, 00115$
  15.         xor     a, #0x80
  16. 00115$:
  17.         jp      P,00103$
  18. ;c_test.c:6: baz = baz + (baz >> 3);
  19.         ld      hl, #4
  20.         add     hl, sp
  21.         ld      b, (hl)
  22.         inc     hl
  23.         ld      c, (hl)
  24.         sra     c
  25.         rr      b
  26.         sra     c
  27.         rr      b
  28.         sra     c
  29.         rr      b
  30.         ld      hl,#4
  31.         add     hl,sp
  32.         ld      a,(hl)
  33.         add     a, b
  34.         ld      (hl),a
  35.         inc     hl
  36.         ld      a,(hl)
  37.         adc     a, c
  38.         ld      (hl),a
  39. ;c_test.c:7: i++;
  40.         inc     de
  41.         jr      00101$
  42. 00103$:
  43. ;c_test.c:9: return i;
  44.         ex      de,hl
  45.         ret
és a z88dk (-O3) - ez rövidebb, de sok a CALL:
Code: ZiLOG Z80 Assembler
  1. ._foo
  2.         ld      hl,0    ;const
  3.         push    hl
  4. .i_3
  5.         ld      hl,4    ;const
  6.         call    l_gintspsp      ;
  7.         ld      hl,8    ;const
  8.         call    l_gintsp        ;
  9.         pop     de
  10.         call    l_lt
  11.         jp      nc,i_4
  12.         ld      hl,4    ;const
  13.         add     hl,sp
  14.         push    hl
  15.         ld      hl,6    ;const
  16.         call    l_gintspsp      ;
  17.         ld      hl,8    ;const
  18.         call    l_gintspsp      ;
  19.         ld      hl,3    ;const
  20.         pop     de
  21.         call    l_asr
  22.         pop     de
  23.         add     hl,de
  24.         call    l_pint_pop
  25.         pop     hl
  26.         inc     hl
  27.         push    hl
  28.         dec     hl
  29.         jp      i_3
  30. .i_4
  31.         pop     hl
  32.         ret

Csak érdekességként ugyanez x64-re fordítva GCC-vel:
Code: [Select]
foo:
.LFB0:
        .cfi_startproc
        xor     eax, eax
        cmp     esi, edi
        jge     .L4
        .p2align 4,,10
        .p2align 3
.L3:
        mov     edx, esi
        add     eax, 1
        sar     edx, 3
        add     esi, edx
        cmp     edi, esi
        jg      .L3
        rep ret
.L4:
        rep ret
        .cfi_endproc

Szerintem inkabb azt kene megvizsgalni, hogy valoban szukseg van-e arra, hogy minden mukodjon 64K-s hatart attorve, vagy elfogadhato, ha adott esetben platform specifikus dolgok vannak, akar pl ugy, hogy a megfelelo C fuggvenynek valo entitassal az ember lapozgat, mintha asm lenne a dolog. Nem tul szep, az igaz.

Ha csak egy nagy méretű tömb kell, akkor annak a kezeléséhez (lefoglalás, felszabadítás, elem olvasása, elem írása) viszonylag könnyen lehet inline asm rutinokat írni. Az már problémásabb, ha a kód + változók + verem is többet igényel, mint 64K.
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: Trefe on 2015.December.22. 18:48:51
Esetleg, ha nosztalgiázni akartok, akkor itt van néhány IS-DOS alatt is futó C compiler és egy interpreter is. Bár, nem mindegyiket próbáltam ki. A legteljesebb ezek közül a Hitech C fordítója 1987-89-ből, egész komoly rutin könyvtárral és használati útmutatóval. A leggyorsabb viszont a MESCC. Mindegyiknek megvan a maga fortélya. Jó kísérletezgetést!
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: Lacika on 2015.December.22. 21:17:11
A MESCC-el hogy kell .com-ot készítni?
A hextobin csak annyit ír ki, hogy Missing colon.
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: IstvanV on 2015.December.22. 22:47:42
A MESCC-el hogy kell .com-ot készítni?
A hextobin csak annyit ír ki, hogy Missing colon.

test.c fordítása A: lemezen:

cc test.c
ccopt test.zsm
zsm test.aaz
hextobin test.hex test.com


A forrás file elején #include <mescc.h> kell a C runtime inicializálásához.
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: lgb on 2015.December.23. 00:29:03
Quote
Ha csak egy nagy méretű tömb kell, akkor annak a kezeléséhez (lefoglalás, felszabadítás, elem olvasása, elem írása) viszonylag könnyen lehet inline asm rutinokat írni. Az már problémásabb, ha a kód + változók + verem is többet igényel, mint 64K.

Valoban. En arra celoztam pont, hogy specialis igenyekre lehet, de ha a C alapfilozofiajat, a pointer aritmetikat stb is at akarja vinni az ember, akkor az nem lenne ilyen egyszeru ... Bar sokszor a fenti is eleg lenne.
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: IstvanV on 2015.December.23. 18:18:57
Újabb fordító teszt: epcompress -raw -m3 kimenetének a kicsomagolása. A forrás file (amit ennél jobban is meg lehetett volna írni :oops:):

[attachurl=1]
[attachurl=2]

Assembly verzió:

[attachurl=3]
[attachurl=4]

Fordítás:

sjasm m3d_test.s m3d_test.com
zcc +enterprise -create-app -O3 -otest_m3d test_m3d.c -lm
sdcc -mz80 --code-loc 0x0200 --data-loc 0x4000 --stack-loc 0xf800 --opt-code-speed test_m3d.c
ihx2ep test_m3d.ihx loader.bin test_m3d.com


A bemeneti file és az időméréshez használt script:

[attachurl=5]
[attachurl=6]

Az eredmény (a z88dk-s program azért ennyire nagy, mert tartalmaz egy 12288 byte méretű statikus tömböt), csak a decompressData rutin futásideje:

[attachurl=7]    (assembly): 0.435 másodperc
[attachurl=8]    (SDCC): 1.943 másodperc
[attachurl=9]    (z88dk): 5.402 másodperc
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: Lacika on 2015.December.24. 10:29:46
Ez a függvény miért működik return nélkül?

itoa(n,s) /*n karakterre konvertalasa s-be */
char s[];
int n;
{
  int i,sign;
  sign=n; i=0;
  do { /* szamjegyek generalasa */
    s[i++]=abs(n%10)+'0';
  } while((n/=10)!=0);
  if(sign<0) s[i++]='-';
  s='\0';
  reverse(s);
}
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: IstvanV on 2015.December.24. 10:48:26
Nincs visszatérési érték, és az eredményt az s[]-be írja.
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: Mayer Gábor on 2015.December.26. 12:50:35
sdcc támogat lapozást z180-nal? ha igen akkor lehet, hogy átlehetne alakítani enterprise z80-hoz.
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: Lacika on 2015.December.31. 11:39:33
Valaki szakavatott meg tudná nézni valami mai debug alkalmatossággal, hogy a csatolt programban hol a hiba?
Rendben lefordul, de CTRL-Z-re ledermed. Amúgy kulcsszavakat számolna, részletesen a program elvi működése itt (http://ep128.hu/Ep_Konyv/C_Programozasi_nyelv.htm#6_3)olvasható.
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: Mayer Gábor on 2015.December.31. 12:26:57
ezt cpm alól futtatod? mert ha nem akkor gondolom nem fog tudni hova kilépni. véget ér a program majd jó eséllyel lefagy a rendszer.
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: Lacika on 2015.December.31. 12:31:00
ezt cpm alól futtatod? mert ha nem akkor gondolom nem fog tudni hova kilépni. véget ér a program majd jó eséllyel lefagy a rendszer.

Ep-n, ISDOS alatt. Ki kellene írnia a begépelt kulcsszavak darabszámát, majd szabályosan kilépne a programból. De valamiért mégsem teszi.
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: Mayer Gábor on 2015.December.31. 13:05:34
kapcsold be fordításkor a warningokat is. megfelelő includok szükségesek pl. stdio.h.
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: Povi on 2016.January.05. 12:37:48

Az eredmény (a z88dk-s program azért ennyire nagy, mert tartalmaz egy 12288 byte méretű statikus tömböt), csak a decompressData rutin futásideje:

(Attachment Link)    (assembly): 0.435 másodperc
(Attachment Link)    (SDCC): 1.943 másodperc
(Attachment Link)    (z88dk): 5.402 másodperc

Nem semmi, több, mint tízszeres lassulás! A másik (négyszeres) még elfogadható szerintem (sőt, kb. azt tartom reálisnak egy asm vs. fordított nyelv esetén).
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: IstvanV on 2016.January.05. 13:44:22
A C verzión még lehetett volna optimalizálni, tehát a fenti időknél gyorsabb is lehetne. :oops: De itt elsősorban a fordítók összehasonlítása volt a cél.
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: IstvanV on 2016.January.05. 18:34:17
Valamivel gyorsabb változat:

[attachurl=1]

SDCC: 1.423 másodperc
z88dk: 4.665 másodperc
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: Povi on 2016.January.06. 12:01:51
nem rossz, azért nagyságrendileg hasonló lett az eredmény :-)
azért az durva, mennyivel lassabb kódot állít elő a z88dk
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: IstvanV on 2016.January.06. 22:45:52
nem rossz, azért nagyságrendileg hasonló lett az eredmény :-)

Még egy kevés javulás (az SDCC verzió valamivel kisebb is lett - lehetne nagyobb és gyorsabb is):
[attachurl=1]

SDCC: 1.328 másodperc
z88dk: 4.532 másodperc

Quote
azért az durva, mennyivel lassabb kódot állít elő a z88dk

Ez már nem egészen fair összehasonlítás, mert a gyorsabb verziók az SDCC-vel készültek (azzal teszteltem, hogy az egyes változtatások javítanak-e a kódon), ezért bizonyos mértékben arra a fordítóra optimalizáltak. De más tesztekben is általában az SDCC jobb kódot generál - legalábbis a C runtime használata nélkül, egész számos aritmetikával. A runtime függvények és a float típus megvalósítása viszont a z88dk-ban tűnnek jobbnak, azzal jobban is futott a mandel.c és a tunnel.c.
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: Alcoholics Anonymous on 2016.January.07. 02:43:24
Ez már nem egészen fair összehasonlítás, mert a gyorsabb verziók az SDCC-vel készültek (azzal teszteltem, hogy az egyes változtatások javítanak-e a kódon), ezért bizonyos mértékben arra a fordítóra optimalizáltak. De más tesztekben is általában az SDCC jobb kódot generál - legalábbis a C runtime használata nélkül, egész számos aritmetikával. A runtime függvények és a float típus megvalósítása viszont a z88dk-ban tűnnek jobbnak, azzal jobban is futott a mandel.c és a tunnel.c.

This translation is going to be terrible so I put the english into code blocks.  Sorry :(



Próbálta már a legújabb z88dk amely egyesíti sdcc és z88dk együtt?

A különbség z88dk és sdcc ez:

sdcc könyvtára minimális, és azt végrehajtani C. Egy maroknyi funkciókat valósították ASM és ezek közé tartozik a 16 bites aritmetikai, memcpy, strcpy, strncpy, strchr, és memset. sdcc a fordító megpróbálja generálni optimalizált fordította C. Az ötlet mögött sdcc könyvtára, hogy C-ben írt, hogy a hordozható annak minden cél CPU-k.

z88dk könyvtár célja a C-szabvány követelményei és meg van írva assembly nyelven. z88dk a fordító megpróbálja létrehozni a kis lefordított C - ezért látod sok hívásokat. Az ötlet mögött z88dk könyvtára, hogy a legtöbb végrehajtási időt fordítanak a könyvtári rutinok így a sebesség szállítják a könyvtár és a kis kód mérete kézbesíti a fordító.

Ha összevetjük a kis C töredékek, amelyek nem élnek könyvtári funkciókat, sdcc akkor mindig gyorsabb kódot, mint z88dk. Azonban a reálisabb programok, ahol könyvtári funkciók fontosak, z88dk gyorsabb lesz, és kisebb. Láttad eltúlzott esetében ez az, amikor összeállítása a float funkciókat. sdcc float könyvtár 32 bites és teljesen C nyelven írt z88dk a 48 bites és teljesen assembly nyelven. z88dk float végrehajtása majdnem 3-szor kisebb, és majdnem 3-szer gyorsabb, mint a sdcc ellenére nagyobb úszós. Hasonló eredményt a 32 bites egész matek, de mind z88dk és sdcc is hasonló teljesítményt nyújt 16 bites egész matematikai mivel mindkettő végre asm.

Láthatjuk néhány benchmark eredmények itt:
http://www.z88dk.org/wiki/doku.php?id=temp:front#benchmarks

Code: [Select]
Have you tried the latest z88dk which combines sdcc and z88dk together?

The difference between z88dk and sdcc is this:

sdcc's library is minimal and it is implemented in C.  A handful of functions are implemented in asm and these include 16-bit arithmetic,  memcpy, strcpy, strncpy, strchr, and memset.  sdcc's compiler tries to generate optimized translated C.  The idea behind sdcc's library is that, written in C, it is portable to all of its target CPUs.

z88dk's library aims for C standard compliance and it is written in assembly language.  z88dk's compiler tries to generate small translated C - that's why you see many calls.  The idea behind z88dk's library is that most execution time will be spent in library routines so the speed is delivered by the library and small code size is delivered by the compiler.

When you compare small C fragments that don't make use of library functions, sdcc will always generate faster code than z88dk.  However, in more realistic programs where library functions are important, z88dk will normally be faster and smaller.   You saw an exaggerated case of this when you compiled using float functions.  sdcc's float library is 32-bit and entirely written in C.  z88dk's is 48-bit and entirely in assembly language.  z88dk's float implementation is almost 3 times smaller and almost 3 times faster than sdcc's despite the larger float type.  Similar results come from 32-bit integer math but both z88dk and sdcc will have similar performance for 16-bit integer math since both are implemented in asm.

You can see some benchmark results here:
http://www.z88dk.org/wiki/doku.php?id=temp:front#benchmarks

sdcc és z88dk is módosult az elmúlt évben el kell végezni kompatibilisek egymással. Az új verzió lehetővé teszi z88dk sdcc kell használni, mint a C fordítót, mialatt a CRT-k és a C könyvtár és javítása sdcc kimenet. Ezek együtt eredményezi kód mérete és sebessége, hogy nagyon jó, mint a kereskedelmi összeállítói.

Ha az új verzió a z88dk telepítve, és egy foltozott sdcc (http://www.z88dk.org/wiki/doku.php?id=temp:front#sdcc1) végrehajtható, akkor össze programokat, mint ez:

zcc +embedded -vn -SO3 -startup=0 -clib=sdcc_iy --max-allocs-per-node200000 test.c -o test

Lesz, aki pragma a csúcsra "test.c" megváltoztatni a org címre:

#pragma output CRT_ORG_CODE = 32768

A kimenet lesz "test_CODE.bin", amely ORGed címen 32.768 ebben az esetben.

Code: [Select]
sdcc and z88dk have been modified in the past year to be made compatible with each other.  The new version of z88dk allows sdcc to be used as C compiler while supplying the crts and C library and improving sdcc's output.  This combination produces results in code size and speed that are very good compared to commercial compilers.

If you have the new version of z88dk installed and have a [url=http://www.z88dk.org/wiki/doku.php?id=temp:front#sdcc1]patched sdcc executable,[/url] you can compile programs like this:

zcc +embedded -vn -SO3 -startup=0 -clib=sdcc_iy --max-allocs-per-node200000 test.c -o test

You will have to add a pragma to the top of "test.c" to change the org address:

#pragma output CRT_ORG_CODE = 32768

The output will be "test_CODE.bin" which is ORGed at address 32768 in this case.

Mert ez a beágyazott célpont nincs stdio stdout, stderr így printf kellene helyettesíteni sprintf vagy sprintf. % f is le van tiltva alapértelmezésben úgy, hogy lehetővé tegye bármely% aefg a könyvtár újra kell építeni. Ez a fajta dolog leírt wiki.

Hogy egyszerűen csak nézd meg a lefordított C nincs, hogy létrehoz egy bináris és tudod használni bármilyen kívánt funkciókat:

zcc +embedded -vn -a -SO3 -clib=sdcc_iy --max-allocs-per-node200000 test.c

Code: [Select]
Because it's the embedded target there is no stdio, stdout, stderr so printf would have to be replaced by sprintf or snprintf.  %f is also disabled by default so to enable any of %aefg the library has to be rebuilt.  That's the sort of thing described in the wiki.

To simply look at the translated C you don't have to generate a binary and you can use whatever functions you want:

zcc +embedded -vn -a -SO3 -clib=sdcc_iy --max-allocs-per-node200000 test.c

Ez a kombináció a z88dk / sdcc mindig gyorsabb és kisebb, mint akár sdcc önmagában vagy z88dk egyedül (kivéve, ha a program tartalmaz sok long), és ez nagyon jó betartását C szabvány. sdcc szállítja a fordító megfelelés és z88dk ellátja a könyvtár betartását.

Sajnos már csak három célokat jelenleg definiált erre a pályára: +cpm +embedded +zx. +embedded az általános cél, és fel lehet használni összeállításához bármilyen Z80 gép, de természetesen a dolgok, mint stdin, stdout, stderr, grafika, hang, stb nem lesz elérhető, mint a célhardver határozatlan.

Code: [Select]
This combination of z88dk/sdcc is always faster and smaller than either sdcc alone or z88dk alone (except when the program contains lots of longs) and it has very good compliance with the C standard.  sdcc supplies the compiler compliance and z88dk supplies the library compliance.

Unfortunately there are only three targets currently defined for this combination:  +cpm +embedded and +zx.  +embedded is the general target and can be used to compile for any z80 machine but of course things like stdin, stdout, stderr, graphics, sound, etc will not be available as the target hardware is undefined.
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: szipucsu on 2016.January.07. 14:48:42
This translation is going to be terrible so I put the english into code blocks.  Sorry :(
I think you should start a topic "C programming (Aztec C / Hisoft C)" in the English forum instead.
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: Povi on 2016.November.11. 11:47:27
Kicsit próbálgattam az Aztec C fordítót:
a UNIX-os "cal" program lefordítva CP/M-re:
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: Povi on 2016.November.11. 11:54:09
Érdekes egyébként ez a régi C forrás (UNIX V6)...

A += és -= operátorok helyett =+ és =- van...

Meg is hülyül tőle a kód :-) Lefordul, csak aztán nem érted, miért fagy le futás közben...

Tudtommal a B nyelvben voltak += és -= operátorok, és a C-ben már megfordították, hogy a "a =- b" kifejezés ne értelmeződjön "a = -b"-nek a "a = a - b" helyett... De ezek szerint akkor még a korai C nyelvben is így volt...
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: Povi on 2016.November.11. 12:27:32
javított com fájl... :oops:

az évet nem írta ki a fejlécbe, valamiért %l formázó karakter volt a printf utasításban (régen lehet, hogy az volt?) a %d helyett...
most már jó
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: Povi on 2016.November.11. 13:37:32
A += és -= operátorok helyett =+ és =- van...

Tudtommal a B nyelvben voltak += és -= operátorok, és a C-ben már megfordították, hogy a "a =- b" kifejezés ne értelmeződjön "a = -b"-nek a "a = a - b" helyett... De ezek szerint akkor még a korai C nyelvben is így volt...

Hm... A Wiki (https://en.wikipedia.org/wiki/C_(programming_language)#K.26R_C) azt írja, csak 1978 óta (a K&R könyv óta) van += és -= operátor. Azelőtt tényleg =+ és =- volt...
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: Lacika on 2016.November.11. 17:27:09
Forrásprogramot lehet kérni?
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: Povi on 2016.November.11. 19:50:00
Forrásprogramot lehet kérni?
a unix v7 cal.c forráskódja módosítás nélkül lefordul:
http://www.tuhs.org/cgi-bin/utree.pl?file=V7/usr/src/cmd/cal.c
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: Povi on 2016.November.11. 21:26:38
kicsit gyorsabb lesz a kód, ha a 116. sor környékét átírod így:

Code: [Select]
register d, i;
helyett ezt:
Code: [Select]
   int d;
    register i;

magyarázat: hatókörönként (kapcsos zárójelen belül) csak egy változó fog regiszterként használódni, a többinek az értéke a RAM-ban lesz eltárolva.
Viszont akkor már érdemesebb a ciklusváltozót regiszterbe rakni, mivel ahhoz fog a legtöbbször hozzányúlni a progi.

Ha több, mint egy változóhoz van register módosító jelző, akkor a legelsőhöz fogja használni az Aztec fordító.

Egyébként nem rossz dolog, hogy az Aztec először ASM forráskódot állít elő, mert így elég egyszerű még kézzel kicsit optimalizálni a kódot. (ilyenkor mindig elgondolkodok, hogy tényleg ez volt a csúcs a '80-as években? manapság el vagyunk kényeztetve a szénné optimalizált fordított kódokkal).

Csatolmányban lásd a kézzel kicsit optimalizált asm kódot és a lefordított .com fájlt. (csak a cal() függvénybe nyúltam bele).
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: Povi on 2016.November.12. 10:21:14
kis kiegészítés...

a CC.COM 8080 assembly-re fordít, ott csak egy változó lehet regiszterben, a BC-be kerül.

a CZ.COM viszont Z80-ra fordít, és három "register"-es változónk lehet, a másik kettőt az IX-be és IY-ba pakolja. Érdekes, hogy ugyanúgy 8080 assembly forráskódot állít elő, a Z80 specifikus (indexregiszteres) utasítások DB-vel vannak benne.
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: Lacika on 2016.November.12. 10:58:39
Kösz az infót! Be is írtam ide (http://ep128.hu/Ep_Konyv/C_Programozasi_nyelv.htm#4_7).
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: lgb on 2016.November.12. 22:32:12
Egyébként nem rossz dolog, hogy az Aztec először ASM forráskódot állít elő, mert így elég egyszerű még kézzel kicsit optimalizálni a kódot. (ilyenkor mindig elgondolkodok, hogy tényleg ez volt a csúcs a '80-as években? manapság el vagyunk kényeztetve a szénné optimalizált fordított kódokkal).

Ezt amugy talan Fejszen :) is kommenteltem: ez nem tudom miert meglepo, ez manapsag is pontosan igy van a UNIX-szeru op'rendszereken pl Linuxon is. Az mas kerdes, hogy "normal" esetben user szamara nem lathato, mert egy pipe-on at atadja az assembler-nek, igy az asm-al nem is talalkozol, de amugy ott van kozben az is, es egyetlen kapcsoloval ra is birhatod, hogy adja oda neked inkabb. Xep128-nal is hasznaltam pl, hogy lassam, mit produkal :-D
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: Povi on 2016.November.12. 23:57:18
Ezt amugy talan Fejszen :) is kommenteltem: ez nem tudom miert meglepo, ez manapsag is pontosan igy van a UNIX-szeru op'rendszereken pl Linuxon is. Az mas kerdes, hogy "normal" esetben user szamara nem lathato, mert egy pipe-on at atadja az assembler-nek, igy az asm-al nem is talalkozol, de amugy ott van kozben az is, es egyetlen kapcsoloval ra is birhatod, hogy adja oda neked inkabb. Xep128-nal is hasznaltam pl, hogy lassam, mit produkal :-D
Nekem meglepő volt, mert nem nagyon használok GCC-t :-)
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: szipucsu on 2016.November.13. 13:12:36
Kösz az infót! Be is írtam ide (http://ep128.hu/Ep_Konyv/C_Programozasi_nyelv.htm#4_7).
Akkor az már nem is az eredeti könyv teljesen, hanem bővített "kiadás".
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: lgb on 2016.November.13. 17:40:42
kis kiegészítés...

a CC.COM 8080 assembly-re fordít, ott csak egy változó lehet regiszterben, a BC-be kerül.

a CZ.COM viszont Z80-ra fordít, és három "register"-es változónk lehet, a másik kettőt az IX-be és IY-ba pakolja. Érdekes, hogy ugyanúgy 8080 assembly forráskódot állít elő, a Z80 specifikus (indexregiszteres) utasítások DB-vel vannak benne.

Ez is erdekes amugy, modern C compilerek meg mindig elfogadjak a "register" kulcsszot, de figyelmen kivul hagyjak, ui az optimalizalo kepessegeik alapjan onalloan, a register szerepeltetese nelkul is regiszterekbe tesznek dolgokat, attol fuggoen, hogy a cel CPU mennyit enged meg, es melyik/melyek az/azok a valtozo(k), amit erdemes szerinte. Foleg 64 bit x86 eseten (mivel ott tobb a regiszter, stb) nezegettem sokszor, hogy pl a gcc milyen kodot general, sokszor egesz meglepo, hogy csak regiszter muveletek vannak, es a kod ranezesre sem irhato meg jobban assembly-ben "kezzel" sem igazan ...

Nekem meglepő volt, mert nem nagyon használok GCC-t :-)

Amugy altalanos UNIX filozofia, nem kifejezetten csak a gcc csinalja ezt :) Tradicionalisan a "cc" nevu parancs a "C compiler" (legyen az gcc vagy mas), az "as" meg az assembler.
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: Lacika on 2016.November.13. 18:22:10
Akkor az már nem is az eredeti könyv teljesen, hanem bővített "kiadás".

Igen, az Aztec és a HiSoft fordítóról van benne némi plusz infó, a Unix-os dolgok viszont kimaradtak belőle (nem sok).
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: lgb on 2016.November.13. 19:22:21
Igen, az Aztec és a HiSoft fordítóról van benne némi plusz infó, a Unix-os dolgok viszont kimaradtak belőle (nem sok).

Amugy szoban forgo C forditok csak a K&R szintaxist tamogattak fuggevenyeknel? Marmint erre gondolok K&R kapcsan:

Code: C
  1. int example (a, b)
  2. char* a;
  3. char* b;
  4. { ... }

Mig manapsag ezt mar nem kifejezetten szokas hasznalni mar, hanem:

Code: C
  1. int example ( char* a, char* b)
  2. { ... }
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: Povi on 2016.November.13. 20:32:02
Amugy szoban forgo C forditok csak a K&R szintaxist tamogattak fuggevenyeknel? Marmint erre gondolok K&R kapcsan:

Code: C
  1. int example (a, b)
  2. char* a;
  3. char* b;
  4. { ... }

Mig manapsag ezt mar nem kifejezetten szokas hasznalni mar, hanem:

Code: C
  1. int example ( char* a, char* b)
  2. { ... }

Az Aztec C a K&R szintaxist támogatja (a régi 7-es UNIX (és a cal.c) is azzal van írva. Az újat nem is fogadja el. A HiSooft-ot nem néztem, most a HiTech-hel próbálkozok. Az egy kicsit többet tud.
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: lgb on 2016.November.13. 20:56:52
Az Aztec C a K&R szintaxist támogatja (a régi 7-es UNIX (és a cal.c) is azzal van írva. Az újat nem is fogadja el. A HiSooft-ot nem néztem, most a HiTech-hel próbálkozok. Az egy kicsit többet tud.

Errol eszembe jut az ELKS project (elvileg "Embeddable Linux Kernel Subset"), ami UNIX-szeru cucc "regebbi" gepekre kb, mondjuk 286-osra. Talaltak hozza egy compiler-t, bcc neven. Az meg csak a K&R szintaxist tamogatta. Ezert irtak egy source "elforditot" ami atalakitja K&R-re elobb, es azt adja a bcc-nek. Brrrrrrrrrrr :-)
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: Povi on 2016.November.13. 21:01:36
Ez is erdekes amugy, modern C compilerek meg mindig elfogadjak a "register" kulcsszot, de figyelmen kivul hagyjak, ui az optimalizalo kepessegeik alapjan onalloan, a register szerepeltetese nelkul is regiszterekbe tesznek dolgokat, attol fuggoen, hogy a cel CPU mennyit enged meg, es melyik/melyek az/azok a valtozo(k), amit erdemes szerinte.

Hasonló az inline kulcsszó a CPP-ben. Azt ugye a makrók kiváltására hozták létre, makrókkal ugyanis elég veszélyes dolgokba is belefuthat az ember... :-)

pl. vegyük ezt az egyszerű függvényt (remélem, nem rontom el :-)):
Code: [Select]
bool IsOdd(int n)
{
    return (n & 1);
}

namármost, ugye ha szép, könnyen karbantartható kódot akarunk, akkor csinálunk egy soros függvényt is akár. Csak hát ugye nagyobb a függvény overhead-je, mint maga a függvény.

Erre találták ki az inline módosítót, amit a függvény elé írva olyan kód jön létre fordításkor, mintha kvázi makró lenne.

Namármost, arra akartam kilyukadni, hogy az inline is olyan, mint a register, hogy opcionálisan veszi figyelembe a fordító, de pl. ha be van kapcsolva az optimalizálás, akkor inline kulcsszó nélkül is "inline-olja" az adott függvényt a fordító, ha úgy gondolja, hogy úgy jobb lenne...
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: Povi on 2016.November.13. 21:10:24
most a HiTech-hel próbálkozok. Az egy kicsit többet tud.
Itt a HiTech C-vel fordított .com.

A Hitech esetén CP/M kompatibilis text file-nak kell lennie a forrásnak, vagyis chr(26) EOF-bájtra kell végződnie. Különben nem hajlandó lefordítani, még a preprocessor kiakad... :-)
Title: Re: C programozás (Aztec C / Hisoft C)
Post by: lgb on 2016.November.14. 00:39:20
Hasonló az inline kulcsszó a CPP-ben.

A CPP az C++ itt? C-ben is van, legalabbis C99 -ben mar igen.

De amugy igen, voltakepp hasonlo, vegulis a mai modern compiler-ek eleg okosak, hogy maguktol is kitalaljak, mikor mi kell, ez igaz kb az inline -ra es a register -re is. Sot, szerintem az esetek 99%-ban (csak tipp persze) rosszabbul is jar az ember, ha megprobal okosabb lenni a forditonal, foleg egy modern architekturan, ahol van mondjuk 32db regisztered, es pl register -nel nem biztos, hogy fejben tartja mar az ember, hogy mit erdmesebb valoban CPU regiszterben tarolni es mit nem :)

Ugyanakkor, a register kulcsszo hasznalata elvileg azt is maga utan vonja, hogy "nincs cime", tehat az ilyen muveletet akkor egyes C forditok meg sem engednek, annak ellenere, hogy amugy a register kulcsszo sok mindenre nincs hasznalva ... Pl:

Code: C
  1. void akarmi ( void ) {
  2.    register int a;
  3.    int *p = &a;   /* gcc eseten forditasi hibat okoz ez a sor, ami persze nincs, ha nincs az elozo sorban ott a "register" kulcsszo ... */
  4.    ... stb ...

Ha nem hasznaljuk viszont a register kulcsszot, attol lehet, hogy a fordito azt csinal belole, am sajat magatol lemond errol, ha pl a cimet akarja valami, mig fentebb pl nem.

Masik hasonlo erdekesseg, hogy miket csinalnak a mai compiler-ek, az pl konkretan az volt, hogy pont emu irasnal futottam abba bele, hogy mi az optimalisabb (itt epp kepet akar renderelni az ember, es a p mondjuk legyen egy pointer ami mutat a kirajzolando pixel-re, a lenti pelda persze nem a valodi eset pont, de most mindegy):

Code: C
  1. *(p++) = ...;
  2. *(p++) = ...;
  3. *(p++) = ...;
  4. *(p++) = ...;
  5. /* A fenti a jobb, vagy pedig ez itt lentebb: */
  6. p[0] = ...;
  7. p[1] = ...;
  8. p[2] = ...;
  9. p[3] = ...;
  10. p += 4;

Raadasul a "p" adott esetben nalam pl egy globalis valtozo volt, mert kell kesobb is. Nos, legalabbis gcc-vel (pont az emlitett -S kapcsolo hasznalataval, hogy lassam milyen asm kodot allit elo), kiderult, hogy a ketto kb tok ugyanazt erredmenyezi. Raadasul igen okos is a fordito: bar a "p" pointer nem igazi "register" tema, mert hat a renderelo fuggveny utan meg kell tartani az erteket, es eleve mint globalis valtozo szerel, stb, a gcc legalabbis azt csinalta, hogy egyszer betoltotte egy regiszterbe es szepen ott hasznalgatta, aztan a fuggveny vegen egyszer irta vissza a memoriaba. Meg az elso esetben is, ahol azt varna pedig az ember, hogy a sok p++ miatt ezt minden lepes utan megcsinalja. Valojaban, ez akar problema is lehet, ha pl multi-thread programunk van, es masik thread is nezi az erteket (es arra szamitunk hogy allandoan no), vagy pl oprendszert fejlesztunk, es interrupt handler, stb, ekkor ugye ajanlatos meg a "volatile" kulcsszot hasznalni, jelezve a forditonak, hogy ne csinaljon ilyen optimalizaciokat, mert lehet, hogy 'varatlanul' kell 'mashol is' az erteke. Na, igazabol - mint mindig - nem tudom normalisan, szepen es eleg precizen kifejezni magam :) de remelem azert ertheto :)

Es akkor lehetne meg olyan erdekessegekrol is beszelni, mint pl a "restrict" kulcsszo szerepe (szinten C99).