| OldComp.cz https://oldcomp.cz/ |
|
| Assembler https://oldcomp.cz/viewtopic.php?f=40&t=421 |
Stránka 4 z 7 |
| Autor: | _dworkin [ 27.08.2013, 18:41 ] |
| Předmět příspěvku: | Re: Assembler |
Busy píše: A na dnes jeden maly trik so skokom doprostred instrukcie Dajme tomu ze mame vyriesit takyto problem: Kód: IF a=ttt THEN a=uuu Ako prve nas napadne jednoduchy priamociary sposob:ELSE IF a=vvv THEN a=www Kód: cp TTT ; Ak A nie je TTT Lenze toto ma az 14 bajtov. Neslo by to trosku zoptimalizovat ?jr nz,NEXT ; tak pokracuj ld a,UUU ; Ak ano tak A=UUU jr END ; Skok na koniec NEXT: cp VVV ; Ak A nie je VVV jr nz,END ; tak skok na koniec ld a,WWW ; A=WWW END: Samozrejme slo, inak by som sa nepytal Kód: cp TTT Vsimnite si ten skok ktory skace o dva bajty dopredu - obskakuje instrukciu LD A,UUU. Pre tento skok sme pouzili dvojbajtovu instrukciu nepodmieneny relativny jump. Lenze, ono existuje aj jednobajtovy nepodmieneny jump o dva bajty ! jr z,SETTT cp VVV jr nz,END ld a,WWW jr END ; Skok o 2 bajty dalej SETTT: ld a,UUU ; LD A,UUU ma 2 bajty END Neverite ? Tak sa pozrite:Kód: cp TTT Tento jednobajtovy jump je dokonca o dva takty rychlejsi, nez ten dvojbajtovy relativny ! jr z,SETTT cp VVV jr nz,END ld a,WWW db #21 ; Kod instrukcie LD HL,dvojbajtovy_operand SETTT: ld a,UUU ; Instrukcia alebo operand pre LD HL,... END: Akurat jedinou jeho nevyhodou je, ze nam nezachova obsah registra HL Nuz ale pokial HL na tomto mieste zrovna nepotrebujeme, tak to predsa nevadi ![]() To reseni vlastne neni zavisle na tribajtove instrukci LD HL,nn ( $21, lo, hi ). Stejne dobre poslouzi i LD BC,nn ( $01, lo, hi ) nebo LD DE, nn ( $11, lo, hi ). Takze lze obetovat libovolnou z tech tri. Dalsi tribajtove jsou ruzne skoky nebo call a ty se nedaji pouzit. Ale jde udelat i toto Kód: cp TTT jr z,SETTT cp VVV jr nz,END ld h,WWW defb $dd ; "Prefix" instrukcie LD ixh,n, popripade $FD pro iyh, SETTT: ld h,UUU ; END: Misto akumulatoru (ve skutecnosti tam teda jde dat cokoliv co zabita 2 bajty) se nastavuje pouze "h"a obetuje se IXH nebo IYH. Obdobne $2E nn = ld l,n a $DD $2E nn je ld ixl,n nebo $FD 2E nn je ld iyl, n. A cele to jde pak prevest na 16 bit kdy misto osmibitoveho "h/l" nebo cast "ix/iy", muzeme nastavovat ld hl,nn a to maskovat za ld ix/iy,nn Kód: Instrukce Čas (T-cykly) Délka Kód (dekadicky) Kód (hexa) LD HL,NN 10 3 33, xx, xx 21, xx, xx LD IX,NN 14 4 221, 33, xx, xx DD, 21, xx, xx LD IY,NN 14 4 253, 33, xx, xx FD, 21, xx, xx ----- LD HL,(NN) 16 3 42, xx, xx 2A, xx, xx LD IX,(NN) 20 4 221, 42, xx, xx DD, 2A, xx, xx LD IY,(NN) 20 4 253, 42, xx, xx FD, 2A, xx, xx ----- LD H,N 7 2 38, xx 26, xx LD HX,N 11 3 221, 38, xx DD, 26, xx LD HY,N 11 3 253, 38, xx FD, 26, xx ----- LD L,N 7 2 46, xx 2E, xx LD LX,N 11 3 221, 46, xx DD, 2E, xx LD LY,N 11 3 253, 46, xx FD, 2E, xx A jeste jsou tribajtove instrukce u kterych si neprepiseme zadny registr, ale pamet. Nejlepsi je asi nejrychlejsi "ld (nn),a" oproti "ld (nn),hl". Problem je jen v tom ze ta adresa musi ukazovat nekam kde to nevadi. A vyssi bajt je zrovna ten druhy kam cpeme nejakou hodnotu. Jde to i otocit na "ld a,(nn)" pak si prepisujeme akumulator a nastavovat muzeme "b,c,d,e,h,l" Na vic jsem zatim neprisel. .) |
|
| Autor: | _dworkin [ 27.08.2013, 19:23 ] |
| Předmět příspěvku: | Re: Assembler |
Kód: IF a=ttt THEN a=uuu ELSE IF a=vvv THEN a=www Nejlepsi reseni je stejne si vhodne zvolit data. Idealni pripad Kód: IF a=ttt THEN a=ttt ELSE IF a=vvv THEN a=vvv Se da prepsat do Z80 bez jedine chyby .) Horsi pripady Kód: IF a=ttt THEN a=ttt+ccc ELSE IF a=vvv THEN a=vvv+ccc Kód: IF a=ttt THEN a=ttt | xxx ELSE IF a=vvv THEN a=vvv | xxx A pokud se ttt vhodne zvoli jako nula tak toho jde udelat hodne misto skoku jen vzorcem. Kód: Prakticky prevod
if a = 0 then dec b else if a =1 then inc b else b je nedefinovano add a,a dec a add a,b ld b,a |
|
| Autor: | pavero [ 28.12.2013, 19:09 ] |
| Předmět příspěvku: | Re: Assembler |
Jak se dá v assembleru číst obsah paměťi nikoliv po bajtech, ale po skupině bitů? Řekněme čtení po pěti bitech. 1. krok - horních pět bitů z prvního bajtu. 2. krok - dolní tři bity z prvního bajtu a horní dva bity z druheho bajtu. 3. krok - dalších pět bitů z druhého bajtu. Atd. Nějaká speciální instrukce, ktera by na toto šla nasadit, asi neexistuje, co? |
|
| Autor: | pavero [ 28.12.2013, 19:13 ] |
| Předmět příspěvku: | Re: Assembler |
Když o tom tak premýšlím, asi mnohem snazší bude varianta po sesti bitech. (8 kroků vs. 3) |
|
| Autor: | Busy [ 28.12.2013, 19:51 ] |
| Předmět příspěvku: | Re: Assembler |
Instrukcie vzdy citaju z pameti cely bajt, dokonca aj ked potrebujes jediny bit. Pokial mas v pameti data usporiadane tak ze nejaky udaj nezabera celych 8 bitov, robi sa to aj tak vzdy tak, ze nacitas cely bajt (alebo cele slovo) a potrebne bity si z toho "vysekas". Cisto prakticka otazka: Naco to potrebujes ? Skus trosku popisat kontext problemu. |
|
| Autor: | pavero [ 28.12.2013, 21:47 ] |
| Předmět příspěvku: | Re: Assembler |
Busy píše: Instrukcie vzdy citaju z pameti cely bajt, dokonca aj ked potrebujes jediny bit. Pokial mas v pameti data usporiadane tak ze nejaky udaj nezabera celych 8 bitov, robi sa to aj tak vzdy tak, ze nacitas cely bajt (alebo cele slovo) a potrebne bity si z toho "vysekas". Cisto prakticka otazka: Naco to potrebujes ? Skus trosku popisat kontext problemu. Tak obecně to lze využít na čtení dat v takovémto formátu uložené. Asi klasický příklad jsou texty, kde používám pouze abecedu, tedy mi stačí jen 32 kombinací. Například Dizzy používá něco obdobného, byť tam je to ještě trochu komplikovanější. Sám to chci použít ve své hře na uložení textů, u kterých nechci, aby byly snadno odhalitelné v hexaeditoru. Vím, že na to by mi dobře posloužila třeba i instrukce cpl, popřípadě nějaké rotace. Zároveň bych tím ale ušetřil i paměť. Asi jako vhodný kompromis použiji 6-bitů na znak, kdy každé tři znaky se vejdou do dvou bajtů, takže čtecí rutinka bude jednoduchá a krátká. |
|
| Autor: | pavero [ 28.12.2013, 21:49 ] |
| Předmět příspěvku: | Re: Assembler |
Opravuji, každé čtyři znaky se vejdou do tří bajtů. |
|
| Autor: | Milsa [ 28.12.2013, 21:55 ] |
| Předmět příspěvku: | Re: Assembler |
Ja mám otázku, niekde som videl, že EXX vymení aj AF a AF' a inde, že tieto registre ostanú nedotknuté. Ako je to teda? |
|
| Autor: | pavero [ 28.12.2013, 21:59 ] |
| Předmět příspěvku: | Re: Assembler |
Milsa píše: Ja mám otázku, niekde som videl, že EXX vymení aj AF a AF' a inde, že tieto registre ostanú nedotknuté. Ako je to teda? Aspoň co já mám vyzkoušené (minimálně v emulátorech), tak instrukce EXX nemění AF/AF', od toho je EX AF,AF' |
|
| Autor: | Busy [ 29.12.2013, 16:32 ] |
| Předmět příspěvku: | Re: Assembler |
pavero píše: Milsa píše: Ja mám otázku, niekde som videl, že EXX vymení aj AF a AF' a inde, že tieto registre ostanú nedotknuté. Ako je to teda? Aspoň co já mám vyzkoušené (minimálně v emulátorech), tak instrukce EXX nemění AF/AF', od toho je EX AF,AF' Kód: int: Vzajomne poradie oboch instrukcii EXX a EX AF,AF nie je kriticke (kedze ich mnoziny posobenia su plne disjunktné), preto ja osobne vzdy pouzivam take ich poradie, ktore v zdrojaku vyzera esteticky lepsie EXX EX AF,AF ..... EX AF,AF EXX EI RET PS1: Uz som sa u ludi zoparkrat stretol s pohladom ze zalozne registre su nejake "ine" a pred navratom z programu ich treba zase "odstrankovat" aby cinnost pokracovala s hlavnymi registrami. Zaujimavy pohlad, ale nespravny. Obidve sady su absolutne rovnocenne, nie je medzi nimi ziadna "hlavna" alebo "zalozna". Je preto uuuplne jedno, ci ich nejaky program necha v skutocnosti vymenene alebo nie. Dolezite je jedine to aby pripadne potrebne hodnoty (vracane z programu) boli v spravnej registrovej banke. PS2: Pokial je na ZX spektre nejaky strojak volany z basicu funkciou USR, v registri HL' (HL ktore prave nie je "nastrankovane") je hodnota #2758 a tato hodnota tam musi byt aj pri navrate nazad do basicu. Je preto uplne jedno, ci strojak vobec nepouzije EXX (a tym HL' nezmeni) alebo pouzije EXX lubovolny pocet (parny ci neparny) krat (a pomeni vsetky registre) ale pred navratom urobi LD HL,#2758:EXX:RET - v oboch pripadoch to bude spravne. |
|
| Autor: | Busy [ 29.12.2013, 18:00 ] |
| Předmět příspěvku: | Re: Assembler |
pavero píše: Tak obecně to lze využít na čtení dat v takovémto formátu uložené. Asi klasický příklad jsou texty, kde používám pouze abecedu, tedy mi stačí jen 32 kombinací. Například Dizzy používá něco obdobného, byť tam je to ještě trochu komplikovanější. Aj keby si pouzil 5 bitov na znak, rutinku to nijak neskomplikuje Sám to chci použít ve své hře na uložení textů, u kterých nechci, aby byly snadno odhalitelné v hexaeditoru. Vím, že na to by mi dobře posloužila třeba i instrukce cpl, popřípadě nějaké rotace. Zároveň bych tím ale ušetřil i paměť. Asi jako vhodný kompromis použiji 6-bitů na znak, kdy každé tři znaky se vejdou do dvou bajtů, takže čtecí rutinka bude jednoduchá a krátká. Btw. prave takyto "5-bitovy" sposob ulozenia textu som pouzil vo svojom intre StoryTalker (video). Text nacitavam z pameti takouto rutinkou: Kód: getznk ld b,#05 Rutinka postupne pri kazdom zavolani nacita jednu 5-bitovu hodnotu z pameti a vrati ju v A. Funguje tak, ze si najprv do registra C nacita cely bajt z pameti, a z tohto bajtu potom narotuje 5 bitov do akumulatora. Ked sa (napr. pri dalsom zavolani) minu vsetky bity v registri C, nacita sa do C novy bajt z pameti a mozu sa vyberat dalsie bity. Rutinka sa da pouzit na vseobecny pocet bitov na jeden nacitavany znak, staci zmenit konstantu #05. Pred prvym zavolanim rutinky treba C inicializovat na hodnotu #00 alebo #80 a do HL nastavit adresu prveho bajtu kde v pameti zacina takto skomprimovany text. A potom pocas nacitavania textu po znakoch zachovat pre rutinku registre C a HL.
xor a getrot rl c jr nz,getbit ld c,(hl) inc hl scf rl c getbit adc a,a djnz getrot |
|
| Autor: | pavero [ 29.12.2013, 23:04 ] |
| Předmět příspěvku: | Re: Assembler |
Paráda Busy, to jsem ani nedoufal, že na tuto úlohu bude stačit takhle krátký a hlavně univerzální kód. Za jaké situace je příznak ZERO nastaven na 1 u instrukce RL? |
|
| Autor: | Busy [ 29.12.2013, 23:33 ] |
| Předmět příspěvku: | Re: Assembler |
pavero píše: Za jaké situace je příznak ZERO nastaven na 1 u instrukce RL? Pri vsetkych rotaciach po shifte #DD sa zero nastavuje podla obvyklych pravidiel - nastavi sa ak je vysledkom operacie (v tomto pripade rotacie) nulovy bajt. Napr. ak mas v C hodnotu #80, nie je nastavene carry a urobis RL C, carry sa zarotuje do nulteho bitu C a tym padom bude v nultom bite C nula. A najvyssi jednotkovy bit vypadne prec, v celom registri C budu vsetky bity nulove a nastavi sa zero.pavero píše: k čemu je tam dobrá ta instrukce scf, když za ní hned následuje rl c, která příznak carry přenastaví dle aktuální situace? Avsak ak je carry pred rotaciou nastavene, potom po rotacii bude nulty bit C nastaveny na jednotku. A zero nastavene tym padom byt nemoze.Tato moja rutinka prave podla priznaku zero testuje, ci uz vyrotovala z registra C vsetky uzitocne bity a ci ho treba znovu naplnit dalsim bajtom. Na zaciatku pri prvom zavolani rutinky (ked je C nastavene na #80) po XOR A nebude carry, a rotaciou vznikne nula, takze C sa naplni bajtom z ramky. Nasledne, hned po vyrotovani prveho najvyssieho bitu prveho znaku, sa vdaka tomu SCF dostane do nulteho bitu jednicka, a ta zabezpeci, ze nasledujucich sedem rotacii nemoze nastavit priznak zero (a register C nebude najplnany z ramky). A az tento nas jednickovy bit vypadne na druhej strane registra C von, co znamena, ze v registri C uz nie su ziadne bity nasich znakov, nastavi sa zero a rutinka podla toho vie, ze musi C znovu naplnit dalsimi datami z ramky. |
|
| Autor: | pavero [ 30.12.2013, 00:17 ] |
| Předmět příspěvku: | Re: Assembler |
Aj, teď mi to konečně docvaklo, vykonání adc a,a vždy v tomto případě vynuluje CARRY, takže do C se pak zprava sypou samé nuly, takže rutinka ví, kdy má skočit na další byte, prostě geniální. A intro StoryTalker je taky boží! |
|
| Autor: | Milsa [ 08.01.2014, 16:59 ] |
| Předmět příspěvku: | Re: Assembler |
Kedysi sme mali na Didaktik Game spektrácky program na výuku assembleru. Nahrávalo sa to z kazety postupne po lekciách. Bolo to v češtine. Myslím, že obsahovo aj pedagogicky to bol výborný program. Nemá to niekto? Samozrejme aj s návodom ako to nahrať do emulátora. |
|
| Stránka 4 z 7 | Všechny časy jsou v UTC + 1 hodina [ Letní čas ] |
| Powered by phpBB® Forum Software © phpBB Group http://www.phpbb.com/ |
|