| OldComp.cz https://oldcomp.cz/ |
|
| Assembler https://oldcomp.cz/viewtopic.php?f=40&t=421 |
Stránka 3 z 7 |
| Autor: | _dworkin [ 21.08.2013, 23:54 ] |
| Předmět příspěvku: | Re: Assembler |
Sakra sakra sakra.. Jak me chybelo neco na zpusob "mov a,[si+bx]" a divat se na ld a,(ix+n) jako na ld a,((ixh+n)+ixl) mne nenapadlo... jak se to pak vubec zapisuje? Kód: DATA: defb 0,1,2,3,4,5,6,7,8,9 CODE: ld ixh,DATA/256 ... ld ixl,4 ; 11:3.......... ld a,(ix+DATA%256) ; ... To uz mne prijde lepsi pouzit (hl) bude to rychlejsi a kratsi. Ix je dobry na nejakou strukturu. Ale kolikrat je lepsi menit strukturu podle toho jak to ctes. - Add 16 bitove registry. Vetsinou se teda snazim vyhnout 16 bitove aritmetice. A kolikrat je proste rychlejsi to delat pres akumulator nez hl = adresa, bc = nejaka promena, hl += bc. Usetrim obsah bc. Kód: ld a,c ; 4:1 add a,a ; 4:1 2*c protoze radek ma 12 word polozek add a,ixh ; 8:2 pridame spravny sloupec add a,ITEM_POZICE % 256 ; 7:2 ld l,a ; 4:1 ld a,ITEM_POZICE / 256 ; 7:2 adc a,0 ; 7:2 ld h,a ; 4:1 hl = adr. v ITEM_POZICE ; 45:12 ... ld b,0 ; 7:2 prijdeme o prvni registr ld hl,ITEM_POZICE ; 10:3 add hl,bc ; 11:1 add hl,bc ; 11:1 ld c,ixh ; 8:2 prijdeme o druhy registr add hl,bc ; 11:1 ; ; 58:10 Nejlepsi je kdyz mas jistotu, ze ti neco neleze pres ten "segment" a staci ti treba "inc l". A uplne idealni kdyz je "offset" nulovy, protoze tam delas nejake cachry. - K tem smyckam a omezeni Z80. Kdyz potrebuji testovat jen jednu promenou ( i nekolikrat ) tak ji mam v akumulatoru pokud to jde. Pokud potrebuji testovat vic promenych tak naopak mam v akumulatoru tu hodnotu na kterou se jiny registr testuje. V prubehu smycky pak akumulator neustale nacita ty spravne hodnoty. Taky pouzivam takovy trik na testovani jinych registru na nulu Kód: inc c dec c ; ano tohle melo byt naopak .) jr z,nn - K tomu flamu o rychlostech. Tak Z80 by mela byt rychlejsi ( ne dramaticky ) a drazsi. Zato zbytek hw je minimalisticke pojeti, takze celkove ta cena byla ( vyrazne ) nizsi. Proc taky cpat nejake udelatka do pocitace, ktery neni ( nebyl ) urcen na hrani. .) Ale ten navrh obrazovky s atributama je nakonec genialni.. i to silenstvi s rozlozenim, aby vetsinu slo delat jen pres 8-bit registry. I ten pro ZX charakteristicky a jasne identifikovatelny "vyber" barev, ktery me kdysi desne ...., ze nemam hnedou treba .) Jak mam kreslit strom, hlavne ze mam fialovou.. Ale na co hneda, kdyz je tam cervena, jak to ze jsem to nepochopil, ze je to R(on/off)G(on/off)B(on/off). A vubec stejne jsem mel CBTV. .) - Na 6502 by melo byt pekne programovat ve Forthu. I kdyz pokud teda ten zasobnik ma jen 256 hodnot.. |
|
| Autor: | Busy [ 22.08.2013, 06:44 ] |
| Předmět příspěvku: | Re: Assembler |
Maly trik ako si moze program sam zistit, na akych adresach sa nachadza: Kód: db #21 <= toto je kod instrukcie LD HL,xxxx pop hl <= nizsi bajt operandu instrukcie LD HL,xxxx jp (hl) <= vyssi bajt operandu instrukcie LD HL,xxxx ld (#4000),hl call #4000 ...a presne na tomto mieste v beziacom kode je v HL adresa presne tohto miesta, nieco ako keby tu v zdrojaku bolo napisane LD HL,$ Inymi slovami, tento kusok programu je de-fakto ako keby instrukcia LD HL,PC (PC=program counter) |
|
| Autor: | Busy [ 22.08.2013, 08:38 ] |
| Předmět příspěvku: | Re: Assembler |
zz_indigo píše: Busy píše: Z80 ma programovo dostupnych dokopy 13 sestnastbitovych registrov a dva bity. Resp. jeden a pol bitu, lebo jeden z nich sa neda programovo citat To cislo sa mi nejak nezda. (AF je nepouzitelne, iX a iY su len indexy, PC a SP detto)a nieje mozne pouzivat registe nakros sadamy AF,BC,DE,HL, AF',BC',DE',HL', IX,IY,IR, SP,PC a este dva bity IFF1 a IFF2 PS: Preco by IX a IY mali byt len indexy ? Mozno s nimi robit vela veci co aj s HL, 16-bitovych aj 8-bitovych. Napriklad ADD IX,BC; INC IX, LD SP,IX. Osembitove napr. ADD A,XL; LD XL,XH. Jedine co nejde je akurat EX DE,HL a vsetky instrukcie po #ED. A este nejde v jednej instrukcii pouzivat naraz obidva IX aj IY. A ohladom AF, to sa tiez zvykne pouzivat ako jeden celistvy 16-bitovy udaj, hlavne v roznych demoefektoch |
|
| Autor: | _dworkin [ 22.08.2013, 09:34 ] |
| Předmět příspěvku: | Re: Assembler |
Busy píše: Maly trik ako si moze program sam zistit, na akych adresach sa nachadza: Kód: db #21 <= toto je kod instrukcie LD HL,xxxx pop hl <= nizsi bajt operandu instrukcie LD HL,xxxx jp (hl) <= vyssi bajt operandu instrukcie LD HL,xxxx ld (#4000),hl call #4000 ...a presne na tomto mieste v beziacom kode je v HL adresa presne tohto miesta, nieco ako keby tu v zdrojaku bolo napisane LD HL,$ Inymi slovami, tento kusok programu je de-fakto ako keby instrukcia LD HL,PC (PC=program counter) Prosim te, nemohl by si to jeste trosku rozvest. Dival jsem se na to a nepochopil to... Chvilku mi trvalo, nez jsem vubec vysel z bludu ze se jedna o SP a pritom je to PC. Pak jsem zkoumal zda neco z toho neni komentar, viz ty prvni 3 radky, ale neni. Pak jsem se dival jaky to ma strojovy kod ty prvni 3 radky a zda to neni nejaky trik kdy skocis doprostred instrukce a ono to udela neco jineho, ale to taky neni ono. Kód: defb $21 ; ld hl,nn defb $e1 ; pop hl defb $e9 ; jp (hl) Proc to teda neni rovnou zapsane jako Kód: ld hl, $e9e1 ; ??? To call by melo delat neco jako Kód: push "Adresa za tretim a teda poslednim bajtem instrukce call nn" : jp NN Jsem uplne mimo. Proc zrovna $4000? Kdybych potreboval to PC tak bych asi musel udelat na to fci Kód: FCE_VRAT_PC:
pop hl ; nacti PC ze zasobniku jp (hl) ; misto RET .... a v kodu call FCE_VRTA_PC ; do hl ulozi PC nasledujici instrukce |
|
| Autor: | _dworkin [ 22.08.2013, 09:43 ] |
| Předmět příspěvku: | Re: Assembler |
Aha, uz me to asi docvaklo kdyz jsem to porovnal s "mym" resenim. Kód: db $21 ; v prvnim pruchodu budou nasledujici 3 bajty chapane jako LD HL,$e9e1 ADRESA_PRO_CALL: pop hl ; <= nizsi bajt operandu instrukcie LD HL,xxxx jp (hl) ; <= vyssi bajt operandu instrukcie LD HL,xxxx ; tohle sem umazal protoze by to udelalo ld (ADRESA_PRO_CALL),$e9e1 a to uz tam je call ADRESA_PRO_CALL ...a presne na tomto mieste v beziacom kode je v HL adresa presne tohto miesta, nieco ako keby tu v zdrojaku bolo napisane LD HL,$ Cele to vypada jako nejaky kod pro zatemneni pri debuggovani co to dela. .) |
|
| Autor: | Busy [ 22.08.2013, 10:05 ] |
| Předmět příspěvku: | Re: Assembler |
_dworkin píše: Busy píše: Maly trik ako si moze program sam zistit, na akych adresach sa nachadza: Kód: db #21 <= toto je kod instrukcie LD HL,xxxx pop hl <= nizsi bajt operandu instrukcie LD HL,xxxx jp (hl) <= vyssi bajt operandu instrukcie LD HL,xxxx ld (#4000),hl call #4000 ...a presne na tomto mieste v beziacom kode je v HL adresa presne tohto miesta, nieco ako keby tu v zdrojaku bolo napisane LD HL,$ Inymi slovami, tento kusok programu je de-fakto ako keby instrukcia LD HL,PC (PC=program counter) Prosim te, nemohl by si to jeste trosku rozvest. Dival jsem se na to a nepochopil to... Chvilku mi trvalo, nez jsem vubec vysel z bludu ze se jedna o SP a pritom je to PC. _dworkin píše: Pak jsem zkoumal zda neco z toho neni komentar, viz ty prvni 3 radky, ale neni. Pak jsem se dival jaky to ma strojovy kod ty prvni 3 radky a zda to neni nejaky trik kdy skocis doprostred instrukce a ono to udela neco jineho, ale to taky neni ono. To je uplne jedno, aj takto sa to da zapisat. Ide len o to, ze do registra HL vlozim operacne kody instrukcii POP HL a JP (HL). Nic viac, a ani o ziadne skakanie doprostred instrukcie sa nejedna.Kód: defb $21 ; ld hl,nn defb $e1 ; pop hl defb $e9 ; jp (hl) Proc to teda neni rovnou zapsane jako Kód: ld hl, $e9e1 ; ??? _dworkin píše: To call by melo delat neco jako Presne tak, to robi CALL.Kód: push "Adresa za tretim a teda poslednim bajtem instrukce call nn" : jp NN _dworkin píše: Jsem uplne mimo. Proc zrovna $4000? Pretoze #4000 je na to idealna adresa. Na mensiu adresu program vo vseobecnosti umiestnit nemozes (tam je romka) a na vyssich adresach si tym LD (adresa),HL mozes program nevhodne prepisat._dworkin píše: Kdybych potreboval to PC tak bych asi musel udelat na to fci A presne toto robi ten moj programcek ! Kód: FCE_VRAT_PC: pop hl ; nacti PC ze zasobniku jp (hl) ; misto RET .... a v kodu call FCE_VRTA_PC ; do hl ulozi PC nasledujici instrukce |
|
| Autor: | Busy [ 22.08.2013, 10:21 ] |
| Předmět příspěvku: | Re: Assembler |
_dworkin píše: Aha, uz me to asi docvaklo kdyz jsem to porovnal s "mym" resenim. No, asi to budem musiet blizsie vysvetlit. Ucelom toho mojho triku je aby si program napisany v asembleri sam vedel zistit, na akej adrese v pameti bezi. To znamena, ze ty ho mozes nahrat do pameti na lubovolnu adresu kam chces, spustis ho od jeho zaciatocnej adresy (tam kde si ho nahral) a program si nasledne sam zisti kde v pameti bezi. Pokial ale v programe pouzijes CALL <adresa_v_ramci_toho_programu> a program nahras do pameti na ine miesto, nez na ake si ho prekladal, tak ten CALL nebude fungovat, pretoze vyzaduje absolutnu adresu a ta po nahrati programu inam uz nebude sediet.Kód: db $21 ; v prvnim pruchodu budou nasledujici 3 bajty chapane jako LD HL,$e9e1 ADRESA_PRO_CALL: pop hl ; <= nizsi bajt operandu instrukcie LD HL,xxxx jp (hl) ; <= vyssi bajt operandu instrukcie LD HL,xxxx ; tohle sem umazal protoze by to udelalo ld (ADRESA_PRO_CALL),$e9e1 a to uz tam je call ADRESA_PRO_CALL ...a presne na tomto mieste v beziacom kode je v HL adresa presne tohto miesta, nieco ako keby tu v zdrojaku bolo napisane LD HL,$ Cele to vypada jako nejaky kod pro zatemneni pri debuggovani co to dela. .) Preto sa v tom mojom priklade umiestnuje funkcia na zistenie PC niekam mimo programu a na pevne zvolenu adresu, aby ju tam mohol CALL zavolat bez ohladu na to, kde si nahral cely program. |
|
| Autor: | _dworkin [ 22.08.2013, 10:23 ] |
| Předmět příspěvku: | Re: Assembler |
Dik uz jsem to pochopil. To ld (#4000),hl je teda vytvoreni toho podprogramu za behu a pak do nej skocis. |
|
| Autor: | _dworkin [ 22.08.2013, 10:28 ] |
| Předmět příspěvku: | Re: Assembler |
Jinak by opravdu stacilo to zapsat jako Kód: ld hl,ADRESA a zbytek nechat na prekladaci.
ADRESA: |
|
| Autor: | Busy [ 22.08.2013, 10:34 ] |
| Předmět příspěvku: | Re: Assembler |
_dworkin píše: Jinak by opravdu stacilo to zapsat jako Popripade takto: Kód: ld hl,ADRESA a zbytek nechat na prekladaci.ADRESA: Kód: ld hl,$+3 V pripade ze program bude spustany vzdy na tej jednej adrese na ktoru bol prelozeny, tak ano, toto by uplne stacilo.
|
|
| Autor: | zz_indigo [ 22.08.2013, 16:27 ] |
| Předmět příspěvku: | Re: Assembler |
Busy píše: zz_indigo píše: Busy píše: Z80 ma programovo dostupnych dokopy 13 sestnastbitovych registrov a dva bity. Resp. jeden a pol bitu, lebo jeden z nich sa neda programovo citat To cislo sa mi nejak nezda. (AF je nepouzitelne, iX a iY su len indexy, PC a SP detto)a nieje mozne pouzivat registe nakros sadamy AF,BC,DE,HL, AF',BC',DE',HL', IX,IY,IR, SP,PC a este dva bity IFF1 a IFF2 PS: Preco by IX a IY mali byt len indexy ? Mozno s nimi robit vela veci co aj s HL, 16-bitovych aj 8-bitovych. Napriklad ADD IX,BC; INC IX, LD SP,IX. Osembitove napr. ADD A,XL; LD XL,XH. Jedine co nejde je akurat EX DE,HL a vsetky instrukcie po #ED. A este nejde v jednej instrukcii pouzivat naraz obidva IX aj IY. A ohladom AF, to sa tiez zvykne pouzivat ako jeden celistvy 16-bitovy udaj, hlavne v roznych demoefektoch Moja chyba. V poznamkach som si nevsinol ze na pracu z Index registramy su vlastne kody. nie rozsirenia povodnych. |
|
| Autor: | dex [ 22.08.2013, 17:44 ] |
| Předmět příspěvku: | Re: Assembler |
Busy píše: Maly trik ako si moze program sam zistit, na akych adresach sa nachadza: Kód: db #21 <= toto je kod instrukcie LD HL,xxxx pop hl <= nizsi bajt operandu instrukcie LD HL,xxxx jp (hl) <= vyssi bajt operandu instrukcie LD HL,xxxx ld (#4000),hl call #4000 ...a presne na tomto mieste v beziacom kode je v HL adresa presne tohto miesta, nieco ako keby tu v zdrojaku bolo napisane LD HL,$ Universum na to používal ne adresu uprostřed RAM, ale adresu v ROM, o které je známo, že se na ní nachází instrukce RET (takže se ZX ROM funguje prakticky vždy, i s většinou těch upravených). CALL 82: DEC SP: DEC SP: POP HL |
|
| Autor: | Busy [ 22.08.2013, 18:30 ] |
| Předmět příspěvku: | Re: Assembler |
dex píše: Universum na to používal ne adresu uprostřed RAM, ale adresu v ROM, o které je známo, že se na ní nachází instrukce RET (takže se ZX ROM funguje prakticky vždy, i s většinou těch upravených). Viem, tento sposob je jednoduchsi, ale rozhodne ho neodporucam pouzivat, pretoze je nespolahlivy. V pripade ze pride prerusenie zrovna uprostred paru instrukcii DEC SP, adresa na zasobniku sa poskodi (nizsi bajt sa prepise vyssim) a na konci bude v HL blbost. Je to sice pravdepodobnost velmi mala, ale je nenulova (a uz sa mi to aj realne stalo). Ciastocne by to riesil zakaz prerusenia, ale co som pozeral, aplikacie ktore tento sposob vyuzivaju, len malokedy prerusenie zakazuju. Ale aj keby aplikacia prerusenie zakazala, este stale to moze pokazit NMI - napr. uzivatel si urobi snapshot zrovna v tomto case...
CALL 82: DEC SP: DEC SP: POP HL |
|
| Autor: | Busy [ 23.08.2013, 08:26 ] |
| Předmět příspěvku: | Re: Assembler |
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
|
|
| Autor: | _dworkin [ 23.08.2013, 23:04 ] |
| Předmět příspěvku: | Re: Assembler |
Toho by se dalo vymyslet jeste vic, jen to bude hodne specificke a nepouzitelne pro vsechno. Staci si seradit instrukce a najit si ty prvni a nebo posledni a kombinovat. Co mne napadlo napr: if zero SMAZ_BC else neco_jineho Kód: ... jr nz,NEMAZ_BC ld bc,0 jr END NEMAZ_BC: ; else neco_jineho END: Tohle by melo pouzit zacatek instrukce ld bc,0 (coz je jedna) jako skok doprostred tech dat a kdyz vyssi bajt bude treba ta nula tak to udela jen 1x nop. Nebo neco jineho, pak to ale nebude nastavovat "b" na nulu, ale na jinou hodnotu. Kód: jr z,SMAZ_BC neco_jineho defb $18 ; jr n SMAZ_BC: ld bc,0 ; $01 $00 (zde muze byt cokoliv, bude to preskoceno) $00 (nop) Kód: Instrukce Čas (T-cykly) Délka Kód (dekadicky) Kód (hexa) NOP 4 1 0 00 LD BC,NN 10 3 1, xx, xx 01, xx, xx LD (BC),A 7 1 2 02 INC BC 6 1 3 03 INC B 4 1 4 04 DEC B 4 1 5 05 LD B,N 7 2 6, xx 06, xx RLCA 4 1 7 07 EX AF,AF' 4 1 8 08 ADD HL,BC 11 1 9 09 LD A,(BC) 7 1 10 0A DEC BC 6 1 11 0B INC C 4 1 12 0C DEC C 4 1 13 0D LD C,N 7 2 14, xx 0E, xx RRCA 4 1 15 0F DJNZ N 13/8 2 16, xx 10, xx LD DE,NN 10 3 17, xx, xx 11, xx, xx LD (DE),A 7 1 18 12 INC DE 6 1 19 13 INC D 4 1 20 14 PS: Skoda jen ze treba u mne ten kod nezabira v podstate skoro nic. Vetsina jsou data. |
|
| Stránka 3 z 7 | Všechny časy jsou v UTC + 1 hodina [ Letní čas ] |
| Powered by phpBB® Forum Software © phpBB Group http://www.phpbb.com/ |
|