Welcome, Guest. Please login or register.


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

Offline geco

  • EP addict
  • *
  • Posts: 7085
  • Country: hu
    • Támogató Támogató
Re: Assembly programozás
« Reply #1080 on: 2021.November.29. 18:42:04 »
Nekem a 0080h rémlik.

Offline Zozosoft

  • Global Moderator
  • EP addict
  • *
  • Posts: 14723
  • Country: hu
    • http://enterprise.iko.hu/
Re: Assembly programozás
« Reply #1081 on: 2021.November.29. 18:43:22 »
exos 5 esetében a 0100h alatti területre meddig nyújtózkódhatok?
005Bh

Valamint saját (5-ös fejlécű) program esetén a 0000-002Fh is szabad préda.

Offline Ferro73

  • EP lover
  • *
  • Posts: 967
  • Country: hu
Re: Assembly programozás
« Reply #1082 on: 2021.November.30. 21:57:02 »
exos 5 esetében a 0100h alatti területre meddig nyújtózkódhatok?

Ha nem használsz több EXOS xx kódot akkor az egész 00h-FFFFh mindet.

Offline Tuby128

  • EP addict
  • *
  • Posts: 1448
  • Country: hu
Re: Assembly programozás
« Reply #1083 on: 2021.December.01. 01:15:21 »
Ez így nem igaz. A 0x38 vagy 038h a megszakítási vektor. Oda legalább egy C9-et kell akkor írni.

Offline Ferro73

  • EP lover
  • *
  • Posts: 967
  • Country: hu
Re: Assembly programozás
« Reply #1084 on: 2021.December.01. 19:48:15 »
Ez így nem igaz.
Ez így nem teljesen igaz.
Meg akkor a ??? 0066h NMI  re is kell. Ki tudja milyen harware-ek lehetnek másoknál.
de akkor már felül írtad.
És ha IM2 használsz ?
Akkor már szabadon használhatod.

Offline geco

  • EP addict
  • *
  • Posts: 7085
  • Country: hu
    • Támogató Támogató
Re: Assembly programozás
« Reply #1085 on: 2021.December.01. 19:56:28 »
ha di mellett fut a minden is,akkor a full memoriat lehet :-D , de ugyi akkor a soft reset is buko,

Offline Ferro73

  • EP lover
  • *
  • Posts: 967
  • Country: hu
Re: Assembly programozás
« Reply #1086 on: 2021.December.02. 21:05:46 »
ha di mellett fut a minden is,akkor a full memoriat lehet :-D , de ugyi akkor a soft reset is buko,
Mivel az EXOS-t kiiktatod.

Offline Zozosoft

  • Global Moderator
  • EP addict
  • *
  • Posts: 14723
  • Country: hu
    • http://enterprise.iko.hu/
Re: Assembly programozás
« Reply #1087 on: 2023.November.30. 10:53:01 »
Mindenki oda van a ChatGPT-ért, hogy hú micsoda profi programozó, aztán még egy 4 soros Z80 programban se képes észrevenni a hibát... :twisted:

User
Mit csinál a következő programkód:

Code: ZiLOG Z80 Assembler
  1.         ld hl,1000
  2. ciklus  dec hl
  3.         jr nz,ciklus
  4.         ret

ChatGPT
A megadott Z80 gépi kód egy egyszerű programot valósít meg, amely a HL regiszterben tárolt értéket csökkenti 1-gyel, majd ágazik vissza a ciklus címkehez, amíg HL nem lesz nulla. A program végén visszatér (ret).

Itt van a kód részletes elemzése soronként:

ld hl, 1000: Betölti a HL regisztert 1000 értékkel.

ciklus: Címkéz egy ciklust, itt kezdődik a tényleges ciklus rész.

dec hl: Csökkenti a HL regiszter értékét 1-gyel (decrement).

jr nz, ciklus: Ugrás a ciklus címkéhez, ha a NZ (not zero) flag beállítva van (azaz HL nem nulla). Tehát, ha HL nem nulla, akkor az ugrás végrehajtódik, és a program visszatér a ciklus elejéhez.

ret: Visszatér a főprogramhoz, vagyis a program befejeződik.

Ez a kód egy egyszerű ciklust valósít meg, amely a HL regiszter értékét csökkenti egészen addig, amíg el nem éri a nulla értéket, majd visszatér a főprogramhoz.


User
Igen, ez lenne a feladata, viszont hibásan működik, soha nem tér vissza. Felismered hol a hiba?


ChatGPT
Igen, látom a problémát a programkódban. A hiba a következő sorban van:


Code: ZiLOG Z80 Assembler
  1. jr nz, ciklus
Ez a parancs a ciklus címkére ugrana, ha a NZ flag beállítva van, tehát a HL regiszter értéke nem nulla. Azonban, mivel az dec hl után azonnal ellenőrizve van a feltétel, a NZ flag mindig beállítva lesz (mivel a Z flag csak akkor lesz beállítva, ha az érték nulla).

A helyes megoldás az, ha az jr nz, ciklus helyett az jr c, ciklus utasítást használjuk. Tehát:


Code: ZiLOG Z80 Assembler
  1. jr c, ciklus
Ez azt jelenti, hogy az ugrás csak akkor történik meg, ha a carry flag be van állítva, ami azt jelenti, hogy az hl értéke kisebb volt, mint 0 (vagyis nem nulla). Ezzel a módosítással a program helyesen működni fog, és a ciklus végén visszatér a ret utasítással.

User
Nem ez a hiba. A módosított programmal pedig már egyből hl=999 értéknél visszatér.


ChatGPT
Elnézést a korábbi félreértésért. Az általad említett kódban valóban látható egy kis probléma, amely miatt a program soha nem tér vissza. Az jr nz, ciklus utasítás mindig végrehajtódik, mert a dec hl mindig beállítja a Z flag-et (Zero flag), így soha nem lesz az NZ (not zero) feltétel igaz.

A javítás érdekében cseréld le az nz feltételt z-re az jr utasításban. Tehát a következőképpen módosítsd:

Code: ZiLOG Z80 Assembler
  1. ld hl, 1000
  2. ciklus dec hl
  3.       jr z, ciklus
  4.       ret
Ez az jr z, ciklus utasítás azt jelenti, hogy az ugrás csak akkor történik meg, ha a Z flag beállítva van (azaz HL nulla). Így a program végrehajtja a ciklust, amíg HL el nem éri a nullát, és visszatér a ret utasítással.

User
Ez a változat sem jó, ennél is már 999-nél visszatér.


ChatGPT
Elnézést a félrevezető válaszokért. A probléma forrása az, hogy az jr utasítás z feltételével való ugrás csak akkor fog megtörténni, ha a Z flag éppen most váltott értéket, tehát a dec hl után. Ha azonban az hl értéke már nullán van, és a dec hl után a Z flag már be van állítva, akkor az jr z, ciklus nem ugrál tovább, mert a Z flag nem fog újra nullára váltani.

Egy lehetséges megoldás az lehet, hogy használj egy másik feltételt az ugráshoz, például a jp nz, ciklus-t. Így a jp (jump) utasítás mindig a ciklus címkére fog ugrani, kivéve, ha HL nullára csökken, amikor a jp utasítás helyett a ret végzi el a visszatérést. Íme a módosított kód:


Code: ZiLOG Z80 Assembler
  1. ld hl, 1000
  2. ciklus dec hl
  3.       jp nz, ciklus
  4.       ret
Ez a kód addig folytatja a ciklust, amíg HL nem éri el a nullát, és csak akkor tér vissza.

User
Elárulom a megfejtést: Z80-nál a 16 bites INC/DEC utasítás nem állítja a flageket, így nem lehet használni a feltételes utasításokat az eredmény ellenőrzésére. Ennek figyelembevételével el tudnád készíteni a javított programkódot?


ChatGPT
Természetesen, most már megértve a problémát, itt van a javított Z80 gépi kód:

Code: ZiLOG Z80 Assembler
  1. ld hl, 1000   ; Kezdeti érték betöltése HL-be
  2. ciklus dec hl ; HL értékének csökkentése
  3.       ld a, h ; HL magasabb byte betöltése az A regiszterbe
  4.       or l    ; A regiszter összeadása az AL alacsonyabb byte értékével (hasonlóan az OR utasításhoz)
  5.       jr nz, ciklus ; Ugrás a ciklushoz, ha az A regiszter nem nulla
  6.       ret    ; Visszatérés, ha az A regiszter nulla
Ebben a kódban a ld a, h utasítással a HL regiszter magasabb byte-ja kerül az A regiszterbe. Az or l utasítással az A regiszter értéke összeadódik az L regiszter értékével, mivel az or utasítás hatása hasonló az összeadáshoz. Ezután az jr nz, ciklus utasítás csak akkor ugrál vissza a ciklushoz, ha az A regiszter nem nulla.

Ez a módszer segít kijátszani azt a korlátozást, hogy az INC/DEC utasítások nem állítják be a Z flag-et a Z80 processzoron.

Offline gflorez

  • EP addict
  • *
  • Posts: 3607
  • Country: es
    • Támogató Támogató
Re: Assembly programozás
« Reply #1088 on: 2023.November.30. 11:20:04 »
Az én szemszögemből nézve ezek a mesterséges intelligenciák nem annyira intelligensek. Az összes emberiséggel kapcsolatos információ birtokában vannak, amit mi adtunk nekik ingyen. De az intelligencia felhalmozódik, és szükségük van az új módszerek megtapasztalására, egy bizonyos őrületre.

Azt mondtam, hogy őrültség? Ez nem az a tulajdonság, amit mi akarunk ezektől az eszközöktől...

--------

From my point of view, these AIs are not so intelligent. They have all the Mankind information, that we gave them for free. But intelligence is accumulative and need experiencing new ways of doing things, a certain madness.

Did I say madness? It is not a quality we want on these tools...

Offline pear

  • EP lover
  • *
  • Posts: 825
  • Country: pl
  • Z80 only
    • Támogató Támogató
Re: Assembly programozás
« Reply #1089 on: 2023.December.01. 08:20:10 »
In my opinion, it's not about madness, but about making mistakes.
It is mistakes that lead to new solutions.
This won't happen in AIs (unless in quantum computers).
----------
Véleményem szerint nem az őrületről van szó, hanem a hibákról.
A hibák vezetnek új megoldásokhoz.
Ez nem fog megtörténni MI-kben (kivéve, ha kvantumszámítógépekben).

Offline Tuby128

  • EP addict
  • *
  • Posts: 1448
  • Country: hu
Re: Assembly programozás
« Reply #1090 on: 2023.December.06. 21:25:30 »
Valaki meg tudná nekem mondani, hogy az Indexregiszteres címzés az összeadással mire jó?

PL: LD A, (IX+d)

Nekem az jutott először eszembe, hogy egy dimenziós char (8 bites) tömb elérésére lehet alkalmas. 16 bitesre már nem jó, mert nincs benne szorzás. (habár a 2-vel és 4-gyel való szorzás bit-shift-tel könnyen megoldható lenne)
Viszont aztán rájöttem, hogy a +d egy konstans amit a OP-kód után adunk meg, emiatt nem is lehet vele dinamikusan tömböt indexelni.

 Egyedül azt tudom elképzelni, hogy a memóriába tettünk változókat egy adott címtől kezdve,
pl.
0. cím -> első változó (1 byte-os)
1. cím -> második változó (1 byte-os)
2. cím -> harmadik változó alsó 8 bites értéke (2 byte-os)
3. cím -> harmadik változó felső 8 bites értéke (2 byte-os)

És akkor így is hivatkozik rá:
LD A,0x23
LD (IX+0),A  - elsó változóba töltjük 0x23 értéket

LD HL,0xAB12
LD (IX+2),L
LD (IX+3),H - harmadik változóba töltjük a 0xAB12 értéket

Ugye ez a megoldás akkor kell, amikor egy szubrutinban több lokális változónk van, mint amennyi regiszter elérhető (BC,DE,HL,IX,IY)

Hátránya ennek a megoldásnak, hogy az indexregiszteres utasítások op kódjai 1 BYTE-tal hosszabbak mint a "normál" regiszteres utasítások, emiatt lassabb a végrehajtása ha tömegesen fordul elő.
Valahol olvastam, hogy némelyik Z80 C-fordítóval az a baj, hogy túlságosan sokat használja az indexregisztereket, ezzel hosszabb lesz a programkód illetve tovább tart a végrehajtás.

Visszatérve a hozzászólás elejére. Vajon egy és kétdimenziós tömböt hogyan lehet indexelni Assembly kóddal a legjobban?

Offline geco

  • EP addict
  • *
  • Posts: 7085
  • Country: hu
    • Támogató Támogató
Re: Assembly programozás
« Reply #1091 on: 2023.December.06. 21:37:58 »
Az IX, es IY regisztereket hasznalo utasitasok hasznalatanak hasznalhatosagat jol leirtad, annyi a lenyeg meg, hogy sebesseg kritikus helyeken az ld (ix),a , ld a,(ix) hasznalata megfontolando, egyeb hasonlo utasitasoke is, mert nagyon lassuak,ez igaz az iy-ra is, mig pl egy ld a,(hl) 7 t-state, egy jo ld a,(ix) 19 t-state-be faj.
Visszaterve az eredeti kerdesre, en barmelyik normal regiszter part hasznalnam a 2 dimenzios tomb elemeinek megcimzesere, lehet pl a DE, a lenyeg az, hogy a tomb kezdete legyen 100h-s hatarra allitva, igy nem kell miden adat eleresnel 16 bites osszeadast elvegezni, E megadja az x coordinatan levo elemet, D -a tomb kezdete megadja az y-t.

Offline geco

  • EP addict
  • *
  • Posts: 7085
  • Country: hu
    • Támogató Támogató
Re: Assembly programozás
« Reply #1092 on: 2023.December.06. 21:53:56 »
Bocs, a 100h-s cimre beallitott tabla kicsit felreertelmezheto volt, a lenyeg az, hogy a tabla alacsony bajtja 00h-n legyen, tehat a tabla kezdocime xx00h legyen, lehet 1300h, 8000h, 9100h, a kodtol fuggoen, szerintem az osszes assemblerben konnyen beallithato, a sjasm-ban pl ha a kododban akarod beloni, akkor a
  defs low -$
tabla_kezdete:
 ezt az igazitast megoldja, egyszerubb megoldas, ha a kodon kivulre helyezed fixen, eleg ennyi:
tabla_kezdete equ 0c000h

Offline Tuby128

  • EP addict
  • *
  • Posts: 1448
  • Country: hu
Re: Assembly programozás
« Reply #1093 on: 2023.December.06. 23:10:04 »
Írtam papíron egy egyszerű c programot amely egy két dimenziós tömböt manipulál:

Ansi C kód 4x4-es tömb, minden második sorát inicializáljuk 255-tel.
Code: [Select]
{
char x=4;  // ezek csak a tömb mérete miatt vannak deklarálva
char y=4;  // ezek csak a tömb mérete miatt vannak deklarálva
char tomb[4][4]; // nem inicializált
char i;
char j:
for (i=0;i<x;i=i+2)
  {
   for (j=0;j<y;j++)
    { tomb[i][j]=255;}
  }
}





Memóriaszervezés:


Code: [Select]
IndexRegiszter kezdőcím +
0. char x
1. char y
2. base address LOBYTE : char TOMB[i][j] - vegyük úgy, hogy a végrehajtáskor már valahova mutat
3. base address HIBYTE : char TOMB[i][j]
4. char i
5. char j

Assembly code (kézzel írtam index regiszter használatával)
Code: [Select]
INIC_FOR_i:
 LD(IX+4),0   ; for(i=0;.....)
FOR_i:
 LD A,(IX+4)  ;A <- char i
 LD L,(IX+0)  ;L <- char x
 CMP L        ;for(...;i<x;...)
 JR C, END_FOR_i ; elöl tesztelt for_i addig hajtjuk végre a ciklust amíg igaz: i<x
INIC_FOR_j:
 LD (IX+5),0  ;for(j=0;.....)
FOR_j:
 LD a,(IX+5)  ;A <- char j
 LD L,(IX+0)  ;L <- char y
 CMP L        ;for(...;j<y;...)
 JR C, END_FOR_j ; elöl tesztelt for_j addig hajtjuk végre a ciklust amíg igaz: j<y
 LD L,(IX+2)
 LD H,(IX+3)  ; HL <- base address of char tomb[][]
 LD BC,HL   ; BC <- base address of char tomb[][]
; most jön a tömb indexelt címének meghatározása: BASE_ADDR + 4*i + j
; elöször 4*i kiszámolása
 LD A,(IX+4) ; A <- char i
 SLA A
 SLA A ; 2x szorzás 2-vel a tömb 2. dimenziója miatt, itt kicsit megdöbbentem, hogy a Z80 nem kérdi, hányszor akarok léptetni
 LD DE,0
 LD E,A      ; DE <- 4*i
 LD HL,0
 LD L,(IX+5) ; HL <- char j
 ADD HL,DE   ; 4*i + j
 ADD HL,BC   ; BASE_ADDR + (4*i+j)
 LD (HL),255 ; tomb[i][j]=255;
 LD A,(IX+5) ; A <- char j
 INC A      ; A++
 LD (IX+5),A ; for(........;j++)
 JR FOR_j ; for(j... a növelés után visszaugrik elöltesztelésre
END_FOR_j:   ; ciklus vége
 LD A,(IX+4) ; A <- char i
 ADD A,2 ; A=A+2
 LD (IX+5),A ; for(........;i=i+2)
 JR FOR_i ; for(i... a növelés után visszaugrik elöltesztelésre
END_FOR_i:   ; ciklus vége
 RET
« Last Edit: 2023.December.06. 23:13:52 by Tuby128 »

Offline Tuby128

  • EP addict
  • *
  • Posts: 1448
  • Country: hu
Re: Assembly programozás
« Reply #1094 on: 2023.December.06. 23:11:05 »
Vélelmezzük, hogy az IX regiszter már oda mutat arra a memóriára, ahol a változók lesznek eltárolva.

Tudom, hogy sok utasítás felesleges, vagy gyorsabb megoldással kiváltható. De az átláthatóság miatt így is megfelel.

 Kérdés, hogy a feltételes JR ugrás vajon fog-e működni?
 Meg hogy a kódban van-e más hiba?
« Last Edit: 2023.December.06. 23:18:03 by Tuby128 »