Strona używa cookies (ciasteczek). Dowiedz się więcej o celu ich używania i zmianach ustawień. Korzystając ze strony wyrażasz zgodę na używanie cookies, zgodnie z aktualnymi ustawieniami przeglądarki.    X

Budujemy własnego asemblera!

Po co?

Cześć! Już wyjaśniam.
Mój język programowania Gamma jest kompilowany poprzez zaprojektowany własnoręcznie kompilator. Jednak nie jest on kompilowany do kodu maszynowego, tylko do czegoś w rodzaju kodu pośredniego, tak zwanego Bytecode. Wiele języków działa w ten sposób, wśród nich możemy wymienić takie potęgi jak Java, C#, Python oraz, chociaż nie widać tego, ale można zobaczyć dzięki Zend Optimizerowi, PHP.

No tak, ale dlaczego?

Budując język mamy w praktyce możliwe trzy wyjścia:
  • Kompilacja do kodu maszynowego
  • Kompilacja do kodu pośredniego i wykonywanie go
  • Interpretowaniu języka "na żywo" prosto z kodu źródłowego
Kompilacja do kodu maszynowego daje niesamowitą szybkość, jednak ogranicza niektóre aspekty języka lub sprawia, że ich implementacja jest niezwykle trudna. Prostym przykładem może być słabe typowanie (chociaż wiem, że za to ktoś mnie zje w komentarzach :)
Jeszcze jedno sprawia, że nie wybrałem kodu maszynowego - Szczerze mówiąc jestem kiepski w asm x86 :)

Interpretowanie języka na żywo powoduje drastyczny spadek wydajności samego wykonania, jednak pozwala na wprost nieograniczone możliwości. W każdym razie spadek wydajności jest niesamowicie duży, co ogranicza samo zastosowanie języka.

Kod pośredni łączy te dwa wyjścia - Sprawia, że wykonanie programu jest w miarę szybkie ponieważ nie musimy intepretować na przykład wyrażeń matematycznych, bo kompilator już to za nas zrobił, a jednocześnie sprawia, że budując własny kompilator, bytecode i maszynę wirtualną, nie zostajemy ograniczeni przez czysto techniczne aspekty procesora.

Pięknie, ale coś tu śmierdzi...

Tak.. wydaje się pięknie do czasu zdania sobie sprawy z tego, że musimy wymyślić coś, co będzie kodem pośrednim.
Wymagania jakie ja postawiłem sobie przed projektowaniem:
  • Ściśle określony format dzięki czemu maszyna się nie zastanawia co właśnie przeczytała
  • Zwięzłość treści - kod wyprodukowany ma być jak najmniejszy
  • Atomowość operacji - Jedna operacja = jeden rozkaz
Patrząc na to wszystko, zdajemy sobie sprawę, że musimy zbudować tak jakby własny komputer, który ma nasz własny procesor i inne podzespoły, zbudować dla niego cały język natywny (asembler) oraz zbudować kompilator tworzący taki język.

Projektowanie

Typów asemblerów jest kilka, ja wybrałem jeden z najprostszych a zarazem najwydajniejszych typów czyli typ oparty o stosy. Różnica polega na tym, że w asm x86 aby coś dodać podajemy parametryzowany rozkaz ADD który wygląda mniej więcej tak:
ADD 2 4
wartość po wykonaniu ląduje w rejestrze akumulatora (eax/rax)
W typie stosowym identyczna instrukcja wyglądać będzie tak:
PUSH 2
PUSH 4
ADD
Rozkaz ADD ściąga dwie wartości ze stosu, dodaje je i wrzuca znów na stos. Plusem takiego rozwiązania jest natywna implementacja odwrotnej notacji polskiej wprost w asemblerze.
Wyrażenie 2+2*2 w odwrotnej notacji polskiej wygląda tak: 2 2 2 * +
Implementacja w asemblerze wygląda prawie tak samo jak zapisana powyżej
PUSH 2
PUSH 2
PUSH 2
MUL
ADD
Po wykonaniu na stosie znajdzie się wartość 6 ponieważ:
na stos dodaliśmy 3 wartości '2', stos wygląda tak: 2 2 2
MUL pobrał dwie wartości, pomnożył i dał na stos. Stos wygląda tak: 2 4
ADD pobrał dwie wartości i je dodał - stos wygląda tak: 6
Voila! I mamy wynik :)

Ogólnym założeniem jakie przyjąłem jest ograniczenie instrukcji parametryzowanych tylko do instrukcji PUSH. Są odstępstwa od tej reguły, ale można je zawsze wyelminować.

Dawaj lepszy przykład!

Kod w gammie wyglądający tak: extern *; writel("Podaj liczbe"); new var = readl(); if(var>5)writel("tak"); else writel("nie"); skompilowany do kodu bajtowego wygląda tak: 0 PUSH 35 7 PUSH 0 14 LABEL 17 CALL writel 27 CALL readl 36 PUSH Podaj liczbe 52 NEW 55 PUSH tak 62 NEW 65 PUSH nie 72 NEW 75 PUSH $0 82 PUSH 1 89 CALL 0 96 PUSH 1 103 CALLP 1 110 NEW 113 PUSH $3 120 PUSH 5 127 HIG 130 IF 133 PUSH $1 140 PUSH 1 147 CALL 0 154 ELSE 157 PUSH $2 164 PUSH 1 171 CALL 0 178 ENDIF 181 HLT Na końcu wpisu zamieszczam opis wszystkich instrukcji w gamma beta 0.1 z opisem, opcjonalnym zadaniem dla was będzie przeanalizowanie wykonania tego programu :)

Po co to?

Dzięki kodu bajtowemu maszyna uruchamiajaca dany program nie musi się zastanawiać, jak zainterepretować dany fragment kodu, tylko ma to podane na tacy. Na przykład, aby odpowiednio sparsować wyrażenie warunkowe, interpreter musi czytać znak po znaku, linia po linii i odpowiednio zapisywać swoje stany (jestem w if czy w else?) a następnie wykonać je. Kompilator robi to podczas kompilacji, a maszyna dostaje na tacy co jak i gdzie, dzięki czemu kod wykonuje się o wiele szybciej.

Implementacja binarna

Same rozkazy to nie wszystko, trzeba wiedzieć jak je zapisać. Zawsze można je zapisać w formie tekstowej (tak jak wyżej podany fragment) i odpowiednio parsować, ale spowoduje to spadek wydajności. Ja postanowiłem zapisać to w innym formacie. Wybrałem format binarny podzielony na niestałe ramki kodu które mają własny adres liczony od początku kodu asm (czyli pomijając nagłówek gammy)
Ramka wygląda tak:
(DŁUGOŚĆ - 2) (ROZKAZ) (FLAGA) (DANE)
Czyli na przykład:
0x3 0x0 0xFE 0x55 da na stos (PUSH) wartość (flaga VALUE) 0x55 czyli 85
Maszyna wirtualna najpierw natrafia na długość całego rozkazu, zapisuje sobie go, czyta dane i po odpowiednim przeczytaniu aktualna pozycja wykonania znów znajduje się na długości rozkazu, tylko że kolejnego :)
Taki ciąg rozkazów interpretowany przez metodę VMRun gammy jest już programem.

Obiecany opis rozkazów oraz flag

Flagi w gammie: EAX = 255 - Identyfikuje akumulator, używane tylko w jednym miejscu VALUE = 254 - Identyfikuje wartość VARIABLE = 253 - Identyfikuje wskaźnik na zmienną STRING = 252 - Identyfikuje ciąg znaków (czytany aż do napotkania 0x00) EMPTY = 251 - Identyfikuje brak danych (np. rozkaz ADD) ARRAY = 250 - Identyfikuje tablicę (listę)

Opis rozkazów: PUSH = 0 -- Daje na stos wartość, wskaznik do zmiennej lub ciąg znaków MOV = 1 -- Pobiera ze stosu wskaznik zmiennej i wartość, następnie ustawia wartość zmiennej na pobraną wartość ADD = 2 -- Pobiera ze stosu dwie wartości, dodaje je i wynik umieszcza na stosie SUB = 3 -- Pobiera ze stosu dwie wartości, odejmuje je i wynik umieszcza na stosie MUL = 4 -- Pobiera ze stosu dwie wartości, mnoży je i wynik umieszcza na stosie DIV = 5 -- Pobiera ze stosu dwie wartości, dzieli je i wynik umieszcza na stosie XOR = 6 -- Pobiera ze stosu dwie wartości, xoruje je i wynik umieszcza na stosie LAND = 7 -- Pobiera ze stosu dwie wartości, wykonuje logiczną koniunkcję i wynik umieszcza na stosie AND = 8 -- Pobiera ze stosu dwie wartości, wykonuje koniunkcję (&&) i wynik umieszcza na stosie LOR = 9-- Pobiera ze stosu dwie wartości, wykonuje logiczną alternatywę i wynik umieszcza na stosie OR = 10 -- Pobiera ze stosu dwie wartości, wykonuje alternatywę (||) i wynik umieszcza na stosie MOD = 11 -- Pobiera ze stosu dwie wartości, dzieli je i resztę z dzielenia umieszcza na stosie NOT = 12 -- Pobira wartość ze stosu, neguje ją i umieszcza na stosie (inaczej niż w C) RSH = 13 -- Pobiera ze stosu dwie wartości, wykonuje bitowe przesunięcie w prawo i wynik umieszcza na stosie LSH = 14 -- Pobiera ze stosu dwie wartości, wykonuje bitowe przesunięcie w lewo i wynik umieszcza na stosie INCR = 15 -- Pobiera wskaznik do zmiennej i dodaje do jej wartości jeden. DECR = 16 -- Pobiera wskaznik do zmiennej i odejmuje do jej wartości jeden. HIG = 17 -- Pobiera ze stosu dwie wartości, sprawdza czy pierwsza jest większa od drugiej i wynik umieszcza na stosie LOW = 18 -- Pobiera ze stosu dwie wartości, sprawdza czy pierwsza jest mniejsza od drugiej i wynik umieszcza na stosie HIGEQ = 19 -- Pobiera ze stosu dwie wartości, sprawdza czy pierwsza jest większa od wieksza lub równa i wynik umieszcza na stosie LOWEQ = 20 -- Pobiera ze stosu dwie wartości, sprawdza czy pierwsza jest mniejsza lub równa od drugiej i wynik umieszcza na stosie EQU = 21 -- Pobiera ze stosu dwie wartości, sprawdza czy są równe i wynik umieszcza na stosie NOTEQ = 22 -- Pobiera ze stosu dwie wartości, sprawdza czy nie są równe i wynik umieszcza na stosie NEW = 23 -- Pobiera ze stosu jedną wartość i tworzy zmienną z tą wartością CALL = 24 -- W przypadku flagi STRING dodaje przekazaną wartość do tablicy używanych funkcji, w przypadku flagi VALUE próbuje wywołac funkcję o podanym ID w kolejności: Wbudowana, Użytkownika, Refleksja JMP = 25 -- Pobiera jedną wartość ze stosu i wykonuje bezwarunkowy skok do adresu o identyfikatorze w tablicy skoków o podanym ID, a poprzednią pozycję zapisuje do stosu skoków LABEL = 26 -- Pobiera ze stosu dwie wartości i zapisuje je do tablicy skoków jako ID i Adres HLT = 27 -- Bezwarunkowe zatrzymanie wykonywania RJMP = 28 -- Pobiera jedną wartość ze stosu i wykonuje relatywny skok do adresu aktualny adres + adres o identyfikatorze w tablicy skoków o podanym ID, a poprzednią pozycję zapisuje do stosu skoków IF = 29 -- Pobiera jedną wartość ze stosu i wprowadza wykonanie w stan warunkowego wykonania. Jeśli TRUE wykonuje aż do instrukcji ELSE a następnie ignoruje instrukcje aż do ENDIF, jeśli FALSE ignoruje instrukcje aż do ELSE, a następnie wykonuje aż do instrukcji ENDIF ELSE = 30 -- Instrukcja oznaczenia częsci ELSE wykonania warunkowego ENDIF = 31 -- Instrukcja końca wykonania warunkowego SLOOP = 32 -- Pobiera dwie wartości ze stosu i dodaje je do stosu pętli jako Adres-Początek i ilość wykonań ENDLP = 33 -- Instrukcja oznaczenia końca pętli. Sprawdza ilość wykonan pętli - jeśli zero przechodzi dalej, jeśli więcej niż zero, dekrementuje licznik i skacze na początek pętli BJMP = 34 -- Pobiera ze stosu skoków jedną wartość i do niej skacze. Skok powrotny. THROW = 35 -- Brak implementacji - skutkuje wyrzuceniem wyjątku o wartości przekazanej. TRY = 36 -- Brak implementacji - Oznaczenie początku bloku łapania wyjątków ASYNC = 37 -- Brak implementacji - Powoduje stworzenie nowego wątku i skoku w nim do podanego adresu BRPNT = 38 -- Brak implemetnacji - Oznaczenie przerwania - Breakpoint SLP = 39 -- Pobiera ze stosu jedną wartość i usypia wątek wykonania na pobrany czas w milisekundach IDLE = 40 -- Nie robi nic LBREAK = 41 -- Instrukcja przerwania wykonania pętli LCONTIN = 42 -- Instrukcja przerwania aktualnego wykonania pętli - ignoruje instrukcje aż do ENDLP COMMENT = 43 -- Nie wpływa na wykonanie programu - dodaje komentarz tekstowy w kodzie asemblera LINE = 44 -- Brak implementacji - oznaczenie aktualnej linii kodu ARRAYINS = 45 -- Wstawia wartość o pobranym ze stosie indeksie i pobranej ze stosu zmiennej wartosc pobrana ze stosu w miejscu pobranym ze stosu ARRAYADD = 46 -- Dodaje wartość o pobranym ze stosie indeksie i pobranej ze stosu zmiennej wartosc pobrana ze stosu na koncu listy ARRAYREM = 47 -- Usuwa wartość o pobranym ze stosie indeksie i pobranym ze stosie miejscu ARRAYCLR = 48 -- Czyści listę o idetyfikatorze pobranym ze stosu CALLP = 49 -- Zachowanie identyczne jak CALL, wartość zwrócona przez funkcję jest dodawana na stos FUNCDEF = 50 -- Definiuje funkcję o podanej nazwie i opcjach zawartych na stosie - ich ilość jest zależna od ilości argumentów funkcji IMPORT = 51 -- Importuje poprzez refleksję podany plik .dll USING = 52 -- Dodaje do tablicy używanych przestrzeni nazw podaną przestrzeń

Jeśli dobrnęliście do końca to jestem z was dumny :D
Do poczytania w kolejnym wpisie! 

oprogramowanie porady programowanie

Komentarze

0 nowych
  #1 09.06.2013 18:43

Gratuluje trudu włożonego w tworzenie własnego języka, ale ze względu na to, że moje umiejętności programistyczne niewiele przekraczają napisanie "Hello Word" w C++ ten wpis pozostanie dla mnie ciekawostką.

aeroflyluby   14 #2 09.06.2013 18:54

@X.A.N.
Przy okazji prezentacji Gammy masz możliwość wyjścia za magiczną granicę printf("hello") :D
Pracuję jeszcze nad dwoma projektami - Lowkick - nakładka na C umożliwiająca trochę łatwiejsze programowanie oraz jeszcze nie nazwany projekt języka dla początków nauki programowania - niesamowicie prosty język w którym każdy się połapie :) Więc czytaj bloga - znajdziesz coś dla siebie :D

blind-oln   7 #3 09.06.2013 19:31

Trochę sztuka dla sztuki.

alucosoftware   7 #4 09.06.2013 20:47

Brawo!

Over   9 #5 09.06.2013 21:59

Podasz np zastosowanie Asemblera w produktach codziennego użytku? Pralka, lodówka etc?

aeroflyluby   14 #6 09.06.2013 22:01

@Over
extern *;
pranie(getMode("30stopni"));

Zadałeś dosyć dziwne pytanie - każda pralka ma jakiś tam kontroler który jest napisany w C lub asemblerze.

aeroflyluby   14 #7 09.06.2013 22:03

@alucosoftware
Dzięki za komentarz, to miło usłyszeć z waszej strony takie coś :D
Może użyjesz gammy do systemu skryptów w spikit?

kubasimov   1 #8 09.06.2013 22:14

Super pomysł. Gratuluje wytrwałości. Chętnie pobawię się językiem.

alucosoftware   7 #9 09.06.2013 22:36

@aeroflyluby
To, że wpis nie zawiera wielu komentarzy nie oznacza, że sam artykuł nie ma wielu odbiorców. Kto wie. Może projekt będzie miał wzięcie.

Zerknij na https://github.com/rsdn/nemerle, może znajdziesz w tym projekcie rozwiązania dla istniejących lub przyszłych przeszkód (pewnie nie raz się pojawią).

aeroflyluby   14 #10 09.06.2013 22:41

@alucosoftware
Dzięki za link, widziałem już ten projekt i mnie zaciekawił, jednak trochę mija się z celem gammy w kilku aspektach:
- Gamma ma być ultra przenośna - aktualnie rozwijam maszyne wirtualna w PHP a w planach mam C i JS
- Kompiluje do IL :<
Zdradzę pewien sekret. Jakieś pół roku temu rozpocząłem budowane sieci neuronowej i w pewnym momencie napotkałem problem. Potrzebowałem dużo lepszych instrukcji warunkowych niż "jedno elementowe". Napisałem wtedy kilka funkcji i tak w sumie zrodziła się gamma. Chodzi o to, że możesz kod bajtowy kompilować i trzymać bezpośrednio w jakiejś zmiennej w C#, bez potrzeby zapisywania go gdziekolwiek, co pozwala na szybkie zmiany oraz szybkie wykonanie nawet kilku łancuchów kodu jeden po drugim oraz wywoływanie z gammy kolejnego kodu gammy.
W każdym razie widzę, że nemerle jest baardzo podobne do gammy :D Więc przyjrzę się bardziej
Dzięki!

  #11 09.06.2013 22:41

hm no dobrze 3+

4lpha   9 #12 09.06.2013 22:52

@aeroflyluby
Zmień nazwę z Lowkick na Lowking cytując klasyka :D

bachus   19 #13 09.06.2013 23:03

@Over: asembler masz wszędzie - od optymalizacji stron internetowych (wstawki w kodzie) po urządzenia wbudowane. Pamiętam, że ostro musiałem tłuc ASM w czasie nauki, chociaż już miałem podstawy-podstaw z czasów 8-bitów (Atari 65XE i słynny Quick Asembler od Avalonu).
@blind-oln: bez "sztuki dla sztuki" nie byłoby postępu i nadal byś siedział przy lampie naftowej...

Autor edytował komentarz.
alucosoftware   7 #14 09.06.2013 23:05

@aeroflyluby
Tu bardziej chodzi mi o klarowny system makr i jego implementację. Wszystko masz wyłożone na talerzu, więc możesz brać do woli to co najlepsze.

okokok   12 #15 09.06.2013 23:37

Wpis bardzo fajny :)

A może ktoś by chciał napisać kurs ASM? Najlepiej tak żeby kompilować program i wrzucać go do bootsectora na dyskietce startowej.

Autor edytował komentarz.
stasinek   10 #16 10.06.2013 09:44

@aero
miałem zapytać przed zgłębianiem kodu o przenośność(już jest odpowiedź)
podoba mi się w gammie możliwość importu funkcji z dowolnego dll(jeśli dobrze zrozumiałem)
jeszcze nie zgłębiałem samego "języka"
a assembler(znam conieco), nie ogarniam jednak do czego Twój interpreter mógłby być przydatny ale temat ciekawy, twórz nie przestawaj

mam pewien program w c(narazie nie ważne co robi) i pewien łącznik socketowy do dorobienia mu gui z "nudów" nawet zacząłem robić prosty serwer http(obsługuje narazie GET mime types i całą liste funkcji "not implemented")
zależało na komunikacji z klientem w html/javascript i przekazywania poleceń poprzez formularze, GET i POST oraz wyniki pośrednie(sprzężenie zwrotne do sterowania) poprzez xml tak aby rozdzielić dwa elementy i umożliwić jakby krzyżowe sterowanie klientów/serwerów każdy z każdym
zastanawiam się gdzie umieścić zasadniczy "przetwornik" jak to rozplanować żeby się nie narobić

hm wywoływanie dowolnych funkcji z dll w gammie brzmi bardzo ciekawie..non stop o tym myśle
zielony jestem w tych sprawach ale czy dałoby się jakoś zaszyć kod gammy w html dodać nagłówek z mime type Twojego języka a następnie sprawić żeby przeglądarka wywołała gamme...
dobra coś bredze

ogólnie za projekt wielki szacun :)

Autor edytował komentarz.
  #17 10.06.2013 10:08

Opracuj lepiej jakiś język programowania www bo css, html, php, javascript to trochę za dużo aby uzyskać pożądany efekt. Proponuję język wspierający szeroko multimedia, grafikę 3D z elemantami wizualnego projektowania interfejsu strony www.

aeroflyluby   14 #18 10.06.2013 11:35

@stasinek, @bitx
Właśnie dlatego piszę maszynę wirtualną w php i javascript ! :D
Chodzi o to, że będzie można wysłać request do serwera z JS w postaci gammy, nastepnie otrzymac response w postaci gammy i go wykonać (np, pokaz wiadomosc)
Można pójść dalej i zbudować cały framework od tego dzięki czemu starczy napisac jeden skrypt i on będzie zarzadzać zarówno JS i PHP

Póki co robię objektówkę - później VM w php a później w JS (bo js jest zły :<)

  #19 10.06.2013 14:22

Mi chodzi o coś takiego czego jeszcze nie ma. Coś co mógłbyś może nawet opatentować. Całkowicie nowy serwer www. Potrzebna by też była zupełnia nowa przeglądarka. Wątpię abyś mógł to sam pociągnąć, ale założenia to sam możesz zrobić.
Ja to widzę tak, że przeglądarka wyświetlałaby stronę zbudowaną w opaciu o pewne komponenty występujące w każdym systemie operacyjnym np. listboxy, textboxy, buttony itp. z tym że te komponenty generowane byłyby w oknie przeglądarki i nie byłyby zasobami wziętymi z danego systemu operacyjnego. Dlatego każda strona zbudowana z tych komponentów czy to na bsd czy win wyglądałaby tak samo. Można by powiedzieć że przeglądarka byłaby taką wirtualną maszyną dla nowego języka.

soanvig   9 #20 10.06.2013 14:40

@bitx
Dzięki dobrze napisanemu CSS i standardom strony wyglądają tak samo. To, do czego zmierzasz, jest całkowitym bezsensem - piękna, ale nierealna idea. I przede wszystkim: po co?

aeroflyluby   14 #21 10.06.2013 14:58

@bitix - To nie ma zbytniego sensu, kiedys pewna kapela nazywała się Microsoft sprobowała czegoś takiego i wyszło jak wyszło (activex).

  #22 10.06.2013 15:03

soanvigu nie jestem zawodowym programistą ani twórcą stron www. Kiedyś programowałem coś w asemblerze na proc 8085 i Z80 i trochę w C w środowisku C Builder. Można powiedzieć, że właściwie nic w tym kierunku nie robiłem. Mnie tylko wydaje się dziwne, że robiąc stronę www troche bardzej skomplikowaną trzeba sięgać po CSS, html, php, javascript, flash. Chociaż muszę przyznać, że aby działać na bazie danych to trzeba jeszcze sql używać tworząc aplikację w C Builderze.

  #23 10.06.2013 21:21

bitx

Do stworzenia strony wystarczy sam HTML :],

4lpha   9 #24 10.06.2013 21:33

@okokok
Świetny pomysł.

aeroflyluby   14 #25 11.06.2013 08:46

@okokok
Sam chętnie bym przeczytał taki artykuł bo jestem jajo w asmx86 póki co :D

  #26 11.06.2013 10:34

ASM to najprostszy z możliwych języków (ale nie najłatwiejszy ;) ) , sam w technikum uczyłem się na 8052, do wykucia jest struktura procesora (gdzie są jakie rejestry, jak się nazywają, co robią) oraz wszystkie polecenia (chyba ich było 107, ale w rzeczywistości ilość ta jest mniejsza bo sam MOV to kilka różnych instrukcji jak MOV A,@R1 i MOV A,R1 to dwie różne instrukcje; pełna lista rozkazowa http://www.8052.com/set8051). Każdy kod w 8052 właściwie zaczyna się od LJMP 50h (0d 03h do 48h są wywołania podprogramów przerywań). Mikroprocesor ma dużo możliwości i jest łatwy w opanowaniu tak że weekend powinien starczyć na rozpoczęcie zabawy. potem już tylko inwencja twórcza i ograniczenia procesora.
Przyznam ze nie bawiłem się innymi niż 8052, ale atmele wypadają lepiej jeśli chodzi o wbudowane dodatki.

stasinek   10 #27 11.06.2013 11:24

okokook po jakiego grzyba wrzucać program do bootsektora?
chcesz reanimować demo scene? :P
na starcie to bedzie nudne bo wymaga nieco wiedzy i czasu
o wiele ciekawiej taki kurs zaczynać od wstawek chcesz? moge napisać od laika dla laika
bo uważam sie za totalnego laika ktory chce tworzyć coś sensownego a nie bawić dla zabawy - szkoda czasu, nie te czasy, mam pare wstawek z wykorzystaniem śp. MMX/3DNow
(rozbudowa funkcji memmove aby kopiować dane nieco szybciej - do kompresora plików) https://dl.dropboxusercontent.com/u/10755180/PC/Koperek/3Dnow_move.c.txt
albo np. funkcja przeszukiwania Boyera Moroe w assemblerze(prawie) przy okazji ktoś mi pomoże to naprawić bo to stary algorytm poszukiwania tekstów przed wykorzystaniem łańcucha hashy i próba reanimacji starych wersji programu kończy się niepowodzeniem, zapętla się w pewnym momencie głównej pętli ECX=0 i wisi w nieskończoność..a działał przecież
https://dl.dropboxusercontent.com/u/10755180/PC/Koperek/boyer_moroe.c.txt
(daje przyśpieche 10% vs C a ogólnie 6x wobec brute-force natomiast nowy algortm z łańcuchem 10x z 300kB/s do 3MB/s - 1GHz procek)
Wniosek - lepiej myśleć nad algorytmem niż nad assemblerem.

Natomiast kto chce może np. w C++ Builderze albo Dev sprawdzić funkcje co jest nie halo?
Bo jest nie halo.

proste wstawki do zliczania ilości cykli od do(benchmark)
https://dl.dropboxusercontent.com/u/10755180/PC/Koperek/cycles.c.txt
znajomość platformy jest przydatna w praktyce - przy dobrym kompilatorze można nauczyć sie nawyków do pisania tak aby linijka kodu zawierała plus minus linijke(lub dwie trzy) prostych operacji a tym samym była możliwie szybka, o np. https://dl.dropboxusercontent.com/u/10755180/PC/Koperek/hdr.c.txt
vs asm(pi razy oko bo to nieco inny format nagłówka)
https://dl.dropboxusercontent.com/u/10755180/PC/Koperek/hdr_asm.c.txt

Narazie nie mam czasu bo tworze coś a w zasadzie przy okazji odgrzebuje stare projekty nie obiecuje że stworze laickie kursy wszystkiego każdego tak łopatologicznie jak przedstawia:
Algorytmy i Struktury Danych Piotr Wróblewski wydawnictwo Helion

Tak na marginesie - aeroflyluby Twoje motto jest genialne, esenscja sensu życia

hind - AVR jest lepsze ale...IAR 8051 albo MSC BASCOM jeszcze lepsze, asembler czymś co warto znać ale nie warto tracić na niego czasu. Lepiej wymyślać sensowne algorytmy

@bitx o np. progress bar - używa windowsowego, linuxowego, mac osowego - jedna linijka kodu
http://www.w3schools.com/tags/tryit.asp?filename=tryhtml5_meter
albo w oparciu o css taki sam na wszystkich systemach - ok 15 linijek kodu
http://jsfiddle.net/RikudoSennin/cwZSW/

Autor edytował komentarz.
aeroflyluby   14 #29 17.06.2013 00:39

@RaveStar - czytając info o fragmentacji ramu przypomniało mi się defragmentowanie dysków SSD - Można to robić, ale po cholerę, skoro odczyt i tak jest taki sam?