OldComp.cz
https://oldcomp.cz/

Assembler
https://oldcomp.cz/viewtopic.php?f=40&t=421
Stránka 37

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 ;-) Takze realne pouzitelnych mame 2x3 a to trinast urcite nieje ;-)
Netvrdim ze vsetky su pristupne priamo ako jeden celistvy 16-bitovy udaj, ale aspon po 8 bitovych castiach ano.

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.
Pre zistenie hodnoty SP nastastie mame jednoduchsie sposoby: LD (adresa),SP alebo ADD HL,SP.
_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.
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 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.
_dworkin píše:
To call by melo delat neco jako
Kód:
push "Adresa za tretim a teda poslednim bajtem instrukce call nn" : jp NN
Presne tak, to robi CALL.
_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
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
A presne toto robi ten moj programcek ! :) Vytvori si presne takuto funkciu FCE_VRAT_PC, umiestni ju na adresu #4000, zavola ju, a funkcia mu vrati adresu ukazujucu do programu presne za miesto volania tejto funkcie. Takze toto si pochopil uplne spravne ;)

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.
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. .)
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.

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
ADRESA:
a zbytek nechat na prekladaci.

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
Kód:
ld hl,ADRESA
ADRESA:
a zbytek nechat na prekladaci.
Popripade takto:
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 ;-) Takze realne pouzitelnych mame 2x3 a to trinast urcite nieje ;-)
Netvrdim ze vsetky su pristupne priamo ako jeden celistvy 16-bitovy udaj, ale aspon po 8 bitovych castiach ano.

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).
CALL 82: DEC SP: DEC SP: POP HL
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...

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
ELSE IF a=vvv THEN a=www
Ako prve nas napadne jednoduchy priamociary sposob:
Kód:
      cp TTT      ; Ak A nie je TTT
      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:
Lenze toto ma az 14 bajtov. Neslo by to trosku zoptimalizovat ?
Samozrejme slo, inak by som sa nepytal ;) Najprv si to trosku preusporiadame:
Kód:
      cp TTT
      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
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 ! :bulb: Neverite ? Tak sa pozrite:
Kód:
      cp TTT
      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:
Tento jednobajtovy jump je dokonca o dva takty rychlejsi, nez ten dvojbajtovy relativny ! :thumbup: A vdaka nemu je nasa rutinka o bajt kratsia :clap: Akurat jedinou jeho nevyhodou je, ze nam nezachova obsah registra HL :shrug: Nuz ale pokial HL na tomto mieste zrovna nepotrebujeme, tak to predsa nevadi :neener:

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 37 Všechny časy jsou v UTC + 1 hodina [ Letní čas ]
Powered by phpBB® Forum Software © phpBB Group
http://www.phpbb.com/