26

Fox napisał/a:

Jeśli nie było to dla Ciebie interesujące, to skąd tak śmiałe tezy?

Zapewne z nadmiaru kompetencji :D

What can be asserted without proof can be dismissed without proof.

27

@Fox: mi po prostu chodziło o coś totalnie innego. Zgadzam się, że 6502 nie jest najlepszy do modelu, w którym stos jest elementem kluczowym.
Pax. I pas.

Pamięć studenta ma charakter kwantowy - student wie wszystko, ale jednocześnie nic nie pamięta.
- Kilka(naście?) pudełek z klawiszami i światełkami. I jeden Vectrex, żeby nimi wszystkimi rządzić.

28 Ostatnio edytowany przez seban (2021-04-20 14:21:02)

Fox napisał/a:

Tu widzę tylko jeden wskaźnik: ctx. Zagnieżdżone struktury mają offsety będące stałymi czasu kompilacji.

100% racji ;) Mój przykład był zbyt mało skomplikowany, nie uwzględniłem tego że faktycznie offsety do poszczególnych pól struktury można określić już na etapie kompilacji.

A już z czystej ciekawości, jak CC65 poradzi sobie jeżeli to będzie tablica wskaźników zawierająca adresy np. stringów?

#include <stdio.h>

#define _countof(array)    (sizeof(array) / sizeof(array[0]))

void main(void)
{
    char *msg[]={"ala ma kota", "atari rulez!", "undercover error?", "super bulgot 3000"};

    for(uint8_t i=0; i < _countof(msg); i++)
    {
        printf("%s\n",msg[i]);
    }
}

ps) wiem że mogę sam sprawdzić, jednak Ty masz to wszystko zapewne w głowie i znasz odpowiedź bez sprawdzania czegokolwiek ;)

29

Lepiej napisać to tak:

static const char * const msg[] = { ... };

I wtedy to jest zwykła tablica o stałym adresie (spoko, non-stop spotykam się z kodem napisanym tak, jak Ty napisałeś :).
Kluczowe jest, czy kompilator zrozumie, że "i" jest w zakresie 0..127 i wtedy:

; AX=i
    asl @
    tay
    lda msg,y
    ldx msg+1,y
    jsr pushax

Tu widać, że w przypadku 65816 nie ma to znaczenia.

https://www.youtube.com/watch?v=jofNR_WkoCE

30 Ostatnio edytowany przez seban (2021-04-20 14:57:32)

Fox napisał/a:

I wtedy to jest zwykła tablica o stałym adresie (spoko, non-stop spotykam się z kodem napisanym tak, jak Ty napisałeś :).

Ale ja specjalnie i z pełną premedytacją tak to napisałem ;D Ciekawy byłem jak dużo rozumie CC65 :D powiem Ci że jeżeli zrozumie to tak jak mówisz, to jestem zdziwiony postępem jego zaawansowania, z tego co pamiętam (naprawdę było to dawno temu) to nie radził sobie tak dobrze... ale jeżeli muszę pisać tak jak napisałeś bo kompilator wtedy "lepiej kompiluje", no cóż... właśnie o to mi chodziło... wątpię aby większość, którzy chcą użyć CC65 będzie się zastanawiała jakie ograniczenia ma 6502, po prostu będą trzaskali taki kod jaki im uchodzi płazem na bardziej zaawansowanych technicznie maszynach.

Do czego zmierzam? Właśnie do tego o czym piszesz, czyli do optymalizacji i rozmienia "durnego" kodu przez kompilator, ja mam do czynienia głównie z GCC/ARM/RISC-V i powiem Ci że nie raz zostałem "zadziwiony" co potrafi zrobić ten kompilator, piszę akurat o GCC bo innych kompilatorów nie  znam i chyba nie mam czasu aby się z nimi zapoznawać... trochę walczyłem z LLVM ale we wczesnych jego wersjach i nie byłem nim jakoś specjalnie zachwycony, dużo wody od tego czasu upłynęło i pewnie się dużo zmieniło... ale ja już nie miałem ochoty do niego wracać.

Reasumując optymalizacja i rozumienie kodu przez kompilator jest kluczowe, tu nie chodzi o to aby nauczyć pisać się pod konkretny kompilator bo ja już tak robiłem wiele lat temu musząc używać "koślawych" kompilatorów dla dziwnych czy wręcz egzotycznych architektur. Nigdy więcej... szkoda było mojego czasu, a zamiast radości z kodowania, męczarnie :)

W przypadku 65xx mam ten komfort że mogę sobie napisać to co chce po prostu w ASM i nie muszę się dodatkowo zastanawiać co zrobi kompilator z kodem którzy stworzyłem używając języka wyższego poziomu, niby po to aby sobie ułatwić sprawę, a potem poświęcając masę czasu na optymalizację (bo np. nie znałem możliwości kompilatora i pisałem w sposób który nijak mu się "nie podobał").

31

Akurat taka optymalizacja w kompilatorze nie jest zbyt skomplikowana: sprawdzasz, że inicjalizator tablicy jest stały i że tablica jest tylko odczytywana. Poprawiłem nie ze względu na wydajność, tylko czytelność kodu - jak widzę taki, jak Twój, to szukam miejsca, gdzie tablica jest modyfikowana oraz dlaczego literały znakowe konwertują się do wskaźnika nie-const - to powinien być błąd kompilacji. Niezależnie, czy targetem jest 6502 czy Xeon.

Bardziej skomplikowana jest analiza zakresu zmiennych.

Jako twórca kompilatora widziałem większe "kwiatki", ale to już przy jakimś piwie kiedyś. I o LLVMie. ;)

https://www.youtube.com/watch?v=jofNR_WkoCE

32

Wow, właśnie odkryłem, że Compiler Explorer ma cc65! https://godbolt.org/z/4YvxdeT7f

https://www.youtube.com/watch?v=jofNR_WkoCE