Welcome, Guest. Please login or register.


Author Topic: Assembly programozás (Read 259291 times)

Offline ergoGnomik

  • EP addict
  • *
  • Posts: 1299
  • Country: hu
  • Stray cat from Commodore alley
Re: Assembly programozás
« Reply #1095 on: 2023.December.07. 08:01:14 »
Valaki meg tudná nekem mondani, hogy az Indexregiszteres címzés az összeadással mire jó?

PL: LD A, (IX+d)
Nem tudom megmondani, de nekem úgy tűnik, mintha kifejezetten jól használható lenne felhasználó által definiált, összetett típusok kezelésénél. struct { típus1 mező1; ... };

Offline geco

  • EP addict
  • *
  • Posts: 7120
  • Country: hu
    • Támogató Támogató
Re: Assembly programozás
« Reply #1096 on: 2023.December.07. 11:38:15 »
Jaa, hogy ilyen kis tömbről van szó, akkor az, amit említettem, fölös, mert nagyon helypazarló, viszont, ha jól látom az ix+4 tárolja az I változót, amit A-ba töltesz, és hasonlítod össze az L-lel, ha A kisebb, mint L, akkor lesz C, így nem hajtódik végre a ciklusod.
JR NC, END_FOR_i ,és JR NC, END_FOR_j    kéne
meg még egy dolgot kiszúrtam a i=i+2-nél:
LD (IX+5),A  helyett LD (IX+4),A kéne.

de a j++ megvalósítható INC (IX+5)-tel
az i=i+2 meg:
INC (IX+4)
INC (IX+4)-gyel

Nem tudom milyen fordítót használsz, van pár, ami nem szereti a LD BC,HL-t, mert ilyen z80 utasítás nincs, ha szereti a fordító, hagyhatod így is, de úgy látom fölösleges is ez az utasítás, mert:
 LD L,(IX+2)
 LD H,(IX+3)  ; HL <- base address of char tomb[][]
 LD BC,HL     ; BC <- base address of char tomb[][]
helyett
 LD C,(IX+2)
 LD B,(IX+3)  ; BC <- base address of char tomb[][]
ez is megadható

Offline geco

  • EP addict
  • *
  • Posts: 7120
  • Country: hu
    • Támogató Támogató
Re: Assembly programozás
« Reply #1097 on: 2023.December.07. 11:52:27 »
itt van egy rövidebb, és index regiszter mentes megvalósítás:
Code: [Select]
tomby   db      04h           ;i
tombx   db      04h           ;j
tombstr defs    tombx*tomby

        ld      hl,tombstr
        ld      bc,(tomby) ;i=4,j=4
        ld      e,b             ;tombx
        ld      d,00h
        ld      a,255
fori    push    bc
forj    ld      (hl),a
        inc     hl
        djnz    forj            ;j--
        pop     bc
        add     hl,de           ;minden páratlan sort átugorjuk
        dec     c               ;i=i-2
        dec     c
        jr      nz,fori
« Last Edit: 2023.December.07. 11:56:34 by geco »

Offline Tuby128

  • EP addict
  • *
  • Posts: 1449
  • Country: hu
Re: Assembly programozás
« Reply #1098 on: 2023.December.07. 12:08:32 »
Most hogy írod LD BC,HL utasításon megint meglepődtem, mint amikor kiderült, hogy bit rotáló útasításnál nem lehet megadni, hogy hányszor végezze el.

Azt olvastam, hogy a HL regiszter, az a 16 bites akkumulátor. Erre kiderül, hogy nincs lehetőség ebből a regiszterből 16 bites értéket másikba tölteni?
Most látom, hogy csak a következő HL utasítások validak:
LD HL,nn
LD HL,(nn)
LD SP,HL
LD (nn),HL

Most ha kiszámolok egy memóriacímet, és LDIR-t akkarok használni, akkor nem tudom áttölteni a BC és DE regiszterekbe az eredményt?
De át tudom, csak 8 bitenként:
LD B,H  (opcode 0x44)
LD C,L  (opcode 0x4D)

Annyiban igazuk van a tervezőknek, hogy mivel az 1 BYTE hosszú opcode-ok beteltek, nincs értelme egy LD BC,HL miatt egy 0xED utáni opcode-ot létrehozni pl: ED 22, mert ugyanúgy két BYTE hosszú lenne, mint amikor végrehajtjuk a 44 4D kódot.

 Megérett már az olyan Z80 FPGA mag, aminek 32 adatbusza van, és ezt a két utasítást egy FETCH utasítással beolvassa, és egy ciklus alatt elintézi.
Ugyanez a véleményem az indexregiszteres címzésre. 32 bites adatbusszal be lehetne olvasni az egész kiterjesztett LD (IX+d),A opkódot egyben, és így visszaírássel együtt 2 ciklus alatt el is intézhető.

 Még annyi finomság lehetne, hogy az indexregiszter által címzett memória a CPU néhány 16 Byte-os CACHE memóriájába lenne töltve, így piszokgyorsan hozzáférne a CPU az adatokhoz. Gyakorlatilag úgy működne mint regiszter. A visszaírás a normál memórába (cache ürítés) lenne problémás - időigényes, amikor az Index regiszter értéket váltana.

Offline Tuby128

  • EP addict
  • *
  • Posts: 1449
  • Country: hu
Re: Assembly programozás
« Reply #1099 on: 2023.December.07. 12:22:33 »
Ez az utasítás mit csinál?

LD HL,(nn)  ;ED 6B nn

Közben megtaláltam:
« Last Edit: 2023.December.07. 12:27:51 by Tuby128 »

Offline kvaczko

  • User
  • *
  • Posts: 51
Re: Assembly programozás
« Reply #1100 on: 2023.December.07. 14:14:43 »
Most hogy írod LD BC,HL utasításon megint meglepődtem, mint amikor kiderült, hogy bit rotáló útasításnál nem lehet megadni, hogy hányszor végezze el.

Azt olvastam, hogy a HL regiszter, az a 16 bites akkumulátor. Erre kiderül, hogy nincs lehetőség ebből a regiszterből 16 bites értéket másikba tölteni?
Most látom, hogy csak a következő HL utasítások validak:
LD HL,nn
LD HL,(nn)
LD SP,HL
LD (nn),HL

Most ha kiszámolok egy memóriacímet, és LDIR-t akkarok használni, akkor nem tudom áttölteni a BC és DE regiszterekbe az eredményt?
De át tudom, csak 8 bitenként:
LD B,H  (opcode 0x44)
LD C,L  (opcode 0x4D)


PUSH HL
POP BC

Offline Tuby128

  • EP addict
  • *
  • Posts: 1449
  • Country: hu
Re: Assembly programozás
« Reply #1101 on: 2023.December.07. 15:42:25 »
Nézegettem a végrehajtási időket:

PUSH HL - 0xE5 - 11 cycles
POP BC - 0xC1 - 10 cycles

LD B,H - 0x44 - 4 cycles
LD C,L - 0x4D - 4 cycles

A köztes memória hozzáférés teszi lassúvá a veremkezelést.

Offline Tuby128

  • EP addict
  • *
  • Posts: 1449
  • Country: hu
Re: Assembly programozás
« Reply #1102 on: 2023.December.08. 16:22:18 »
Gondolkodtam, hogy ha a verem a cache-ben lenne akkor mennyivel gyorsulnának fel a dolgok.
 Az a baj, hogy a Z80 verem utasításai a 16 bites mozgatásban kimerülnek. Nem lehet a veremből kivenni a 4. elemet hogy feldolgozzuk, aztán visszategyük. Emiatt az az érzésem, hogy rengeteg globális változó esetén inkàbb az indexregiszterek lesznek jól használhatók. Főleg azért mert az indexregiszterek által címzett memória közvetlenül is manipulálható. Pl matematikai utasítások végezhetőek el az ix által címzett memórián lévő érték és az akkuval. Tölthető a címzett memória bármelyik regiszterbe majd onnan vissza. Stb.
 Persze lassú a jelenlegi állapotában, de ha kicserélem a Z80-at egy fpga-ra, akkor a cache-be töltöm az indexregiszter által címzett memóriát, és máris minden utasítás csak 2-4 ciklus lesz.

Offline Tuby128

  • EP addict
  • *
  • Posts: 1449
  • Country: hu
Re: Assembly programozás
« Reply #1103 on: 2023.December.08. 20:49:08 »
Mi történik akkor, ha a egy valódi z80 egy illegális utasítást kap. Itt most nem a nem-dokumentált utasításra gondolok, hanem egy tényleg nem létező utasításra.
Egy opkódos utasításból nincs ilyen, de pl ED után ha C0 ... FF áll, akkor az nem létezik.
Ilyenkor mi van? Hogyan reagál rá a programszámláló? Átugorja a második opkódot és folytatja tovább a dolgát?

Offline Ferro73

  • EP lover
  • *
  • Posts: 980
  • Country: hu
Re: Assembly programozás
« Reply #1104 on: 2023.December.08. 21:13:44 »
Emlékeim szerint úgy fog reagálni mint a ZX nél az in a,(0FEh) és a in a,(0FCh).

Asmon-ban ellenőriztem. itt leltem a nem dokumentált utasításokra is.
Volt egy A4 lap ZX könyvben ahol fel volt tüntetve mind a 256
DEC HEX AS.CI Z80 utasítás  CD xx utasítás ED xx utasítás.
ezeknek a hiányzó részeit próbálgattam.

Offline Tuby128

  • EP addict
  • *
  • Posts: 1449
  • Country: hu
Re: Assembly programozás
« Reply #1105 on: 2023.December.08. 21:25:06 »
De mi volt pontosan. Emlékszel még?

Offline kvaczko

  • User
  • *
  • Posts: 51
Re: Assembly programozás
« Reply #1106 on: 2023.December.08. 21:54:35 »
Gondolkodtam, hogy ha a verem a cache-ben lenne akkor mennyivel gyorsulnának fel a dolgok.
 Az a baj, hogy a Z80 verem utasításai a 16 bites mozgatásban kimerülnek. Nem lehet a veremből kivenni a 4. elemet hogy feldolgozzuk, aztán visszategyük. Emiatt az az érzésem, hogy rengeteg globális változó esetén inkàbb az indexregiszterek lesznek jól használhatók. Főleg azért mert az indexregiszterek által címzett memória közvetlenül is manipulálható. Pl matematikai utasítások végezhetőek el az ix által címzett memórián lévő érték és az akkuval. Tölthető a címzett memória bármelyik regiszterbe majd onnan vissza. Stb.
 Persze lassú a jelenlegi állapotában, de ha kicserélem a Z80-at egy fpga-ra, akkor a cache-be töltöm az indexregiszter által címzett memóriát, és máris minden utasítás csak 2-4 ciklus lesz.

A verem by definition egy LIFO tároló. Innéttől nincs értelme a “kiveszem belőle az x-ik elemet” dolognak. Az a RAM. A processzor cache viszont nem egy RAM, a felhasználó programja nem is férhet hozzá. Ha FPGA-n belül akarsz gyors elérést az indexregiszterek által megcímezhető memóriacímekhez, azt megteheted az FPGA belső RAM-jával. Ugyanakkor meg kell oldanod azt is, hogy ez szinkronban legyen a tényleges RAM-mal, hiszen egy következő utasítással akár direkt címzéssel is hozzá kell tudj férni. A bottleneck (ha az), továbbra is megmarad - hozzá kell nyúlnod a RAM tartalmához. Akkor meg nem vagy előrébb, legfeljebb az “FPGA cache” olvasásakor, ott is leginkább az 1-30ns vs. 70-120ns között van valójában időelőnyöd. Ha az Enterprise 2.0-dat 10ns elérési idejű RAM-mal pakolod tele, akkor ez a kérdés meg eleve okafogyott.

Offline Tuby128

  • EP addict
  • *
  • Posts: 1449
  • Country: hu
Re: Assembly programozás
« Reply #1107 on: 2023.December.09. 00:50:08 »
Kvaczko, a 8086-os processzornál kezdték használni a
LOAD HL, (SP+dd) utasításokat. Veremnek hívták továbbra is.
Ha jött egy szubrutin, aminek dinamikusan kellett 5 integer változó, akkor SUB SP, 4byte*5, szépen eltolták a SP kezdőcímét visszafelé (a verem mérete visszafelé növekszik). És akkor jött a LOAD HL,(SP+2) ill. LOAD (SP+2),HL meg hasonlók.
Ha visszatért a szubrutin egy RETURN paranccsal akkor az SP-t visszatolta az eredeti helyére ADD SP,4byte *5.

A lényeg, hogy 8086-ostól kezdve már nem csak LIFO volt, hanem egy indirekt elérésű tároló, mint ami az EP-nél az IX regiszterek valósítnak meg.
Ez az eljárás nagyon szépen támogatta a C és PASCAL programnyelveket.

 Miért mondod, hogy a processzor cache nem ram? Pont hogy a leggyorsabb statikus ram, ami a processzor órajelén működik. Az a feladata, hogy a memóriából egy szeletet eltároljon, amivel a processzor most éppen nagyon sok műveletet végez. A cache nem egy 65535 x 65535-ös tömb feltöltésére való, hanem arra ha van egy szubrutin, ami dolgozik 20-40 változóval, akkor azokat eltárolja és a végrehajatást gyorsítsa.

 A bottlenek problémát értem. FPGA esetén lehetőségem lenne, megnövelni a Z80 adatbuszát 8 bitről 16-ra vagy 32-re. Ezzel a módszerrel egy órajel alatt 2x illetve 4x annyi op-kódot vagy adatot tudnék kiolvasni. Egy 16bites értékadás LD HL,0x335F (opcode 12 nn nn) vagy egy indexregiszeres értékolvasás LD a,(IX+d) (opkód: DD 7E dd) opkódja 3 BYTE hosszú. Kiterjesztve az adatbuszt 32 bitre, mindezt 1 órajel alatt ki tudnám olvasni. Másik 1 órajel alatt végrehajtani, letárolni.
« Last Edit: 2023.December.09. 00:57:07 by Tuby128 »

Offline Tuby128

  • EP addict
  • *
  • Posts: 1449
  • Country: hu
Re: Assembly programozás
« Reply #1108 on: 2023.December.09. 00:56:26 »
->

Offline Ferro73

  • EP lover
  • *
  • Posts: 980
  • Country: hu
Re: Assembly programozás
« Reply #1109 on: 2023.December.09. 19:37:29 »
De mi volt pontosan. Emlékszel még?

Ha a CD xx utasítás készletet nézem emlékeim szerint CD 00- CD 03 van utasítás és CD 04 - CD 07 üres nem dokumentált.
a CD 04 - CD 07 megegyezett a CD 00 -CD 03.
De, hogy melyik CPU Z80A, Z80B vagy Z80C már nem emlékszem.