eGospodarka.pl
eGospodarka.pl poleca

eGospodarka.plGrupypl.comp.programmingDo osób znających instrukcje procesora Z80
Ilość wypowiedzi w tym wątku: 8

  • 1. Data: 2011-06-18 18:13:05
    Temat: Do osób znających instrukcje procesora Z80
    Od: "Piotrek" <p...@p...onet.pl>

    Parę miesięcy temu nosiłem się z zamiarem napisania emulatora jakiejś
    rzeczywistej maszyny, wybór padł na ZX Spectrum i procesor Z80. Od jakiegoś
    czasu wcielam swój plan w życie, tzn. pieczołowicie emuluję kolejne instrukcje
    procesora i potwierdziło się to, czego się obawiałem-nie rozumiem jak
    instrukcje odejmowania oddziałują na pewne flagi (tzn. dlaczego oddziałują
    inaczej niż mi się zdaje). Z manuali i stron, którymi się posiłkuję, można
    wyczytać między wierszami, że odejmowanie z technicznego punktu widzenia
    niczym nie różni się od dodawania, tzn. procesor Z80 operację odejmowania
    wewnętrznie i tak konwertuje sobie do operacji dodawania, jedynie stan flagi N
    odróżnia te działania od siebie, cała arytmetyka odbywa się w kodzie
    uzupełnieniowym do 2. Coś mnie jednak tknęło i poprosiłem na pewnym
    anglojęzycznym forum o zweryfikowanie moich przypuszczeń co do wyników trzech
    przykładowych działań i okazało się, że we wszystkich trzech przypadkach się
    myliłem (w każdym wynik był dokładnie przeciwny niż sądziłem).

    Załóżmy, że ograniczymy rozważania do operacji na rejestrach 8-bitowych. Moje
    wątpliwości dotyczyły zachowania flag C (przeniesienia, ustawianej gdy nastąpi
    przeniesienie z bitu 7, tzn. wynik nie zmieści się na 8 bitach) i H
    (półprzeniesienia, ustawianej gdy dojdzie do przeniesienia z bitu 3 na 4).

    Rozpatrywane były następujące operacje:

    1) działanie 3 - 5 (w praktyce załadowanie pierwszej wartości do rejestru A i
    wykonanie instrukcji SUB 5).

    Moim zdaniem nie dojdzie tu do półprzeniesienia, zdaniem mojego dyskutanta-tak.
    Oto jak rozumowałem:

    3 - 5 to dla procesora de facto 3 + (-5), 3 to bitowo 00000011,
    -5 to 11111011 (działamy w U2).

    Zapisując to jedno pod drugim i rachując pisemnie od prawej do lewej (od
    najmłodszego bitu do najstarszego) i zakładając, że procesor liczy to tak
    samo, dostaję kolejno:

    - na pozycji 0 sumę 1 + 1 -&gt; mamy przeniesienie z bitu 0 na 1
    - na pozycji 1 sumę 1 + 1 + 1 (przeniesienie) -&gt; mamy przeniesienie z 1 na 2
    - na pozycji 2 sumę 0 + 0 + 1 (przeniesienie) -&gt; brak przeniesienia z 2 na 3

    Ponieważ ostatnie działanie nie wygenerowało nowego przeniesienia, a dalej nie
    mamy już sytuacji, w której sumowalibyśmy dwie jedynki, nie ma bata, żeby
    wygenerowało nam się nowe przeniesienie, w szczególności przeniesienie z bitu
    3 na 4. Zdaniem mojego dyskutanta jednak występuje. Gdzie tu błądzę?


    2) działanie 11 - (-5)

    Tu według mojego rozumowania procesor tłumaczy sobie to odejmowanie na
    dodawanie 11 + 5. Dalej, postępując analogicznie jak w przypadku 1), widzę jak
    byk przeniesienie z bitu 3 na 4, którego zdaniem mojego dyskutanta nie ma.
    Wygląda na to, że błądzę tak, jak w przypadku 1), tylko nie wiem dlaczego.

    3) Postawiłem tezę, że odjęcie czegokolwiek od 0 nie może spowodować żadnego
    przeniesienia. Mój argument: skoro dla Z80 0 - cokolwiek to w rzeczywistości
    0 + (- cokolwiek), a 0 bitowo to po prostu 00000000, nie możemy przy
    którejkolwiek parze bitów dostać sumu większej od 1, więc nie ma mowy o
    przeniesieniu na którejkolwiek pozycji. Mój dyskutant oczywiście stwierdził,
    że mylę się po raz trzeci i odjęcie od 0 czegokolwiek poza 0 wygeneruje i
    przeniesienie, i półprzeniesienie. Za prawdziwością tego, co mówi, przemawia
    niestety też jedna z oficjalnych dokumentacji, która w odniesieniu do
    instrukcji NEG (która jest właśnie odjęciem wartości rejestru A od 0 i
    wstawieniem do tegoż rejestru wyniku tego działania) mówi, że flaga C ma być
    ustawiona zawsze z wyjątkiem sytuacji, w której przed wykonaniem instrukcji
    rejestr A zawierał wartość 0.

    Zastanawiające jest to, że mój tok rozumowania we wszystkich przypadkach
    prowadzi do stwierdzenia będącego negacją stanu faktycznego. Wygląda na to, że
    nie myślę źle, tylko moje rozumowanie opiera się na jakiejś błędnej
    przesłance. Niestety, mojemu dyskutantowi nie chciało się już wczytywać w mój
    tok myślenia prowadzący do złych wyników, mam nadzieję, że komuś z Was zechce
    się wyprowadzić mnie z błędu. Odsyłanie mnie do literatury raczej w niczym tu
    nie pomoże-przeglądam równolegle kilka manuali i właściwie żaden nie rozwiewa
    moich wątpliwości. Owszem, da się w nich znaleźć przykłady na to jak operacje
    dodawania wpływają na stan poszczególnych flag, ale o odejmowaniu praktycznie
    się nie wspomina, ewentualnie sugeruje się tylko, że przy odejmowaniu &quot;jest
    tak samo&quot;. Wygląda na to, że jednak nie do końca, dlatego też bardzo proszę
    Was o wytknięcie mi błędów w rozumowaniu.

    --
    Wysłano z serwisu OnetNiusy: http://niusy.onet.pl


  • 2. Data: 2011-06-18 18:47:58
    Temat: Re: Do osób znających instrukcje procesora Z80
    Od: Sebastian Biały <h...@p...onet.pl>

    On 2011-06-18 20:13, Piotrek wrote:
    > czego się obawiałem-nie rozumiem jak
    > instrukcje odejmowania oddziałują na pewne flagi

    http://mamedev.org/release.html

    Rozpakuj, poszukaj CPU Z80 i z kodu dowiesz się jak działa. Osoby mające
    pojęcie o Z80 w takich szczegółach chyba juz wymarły ;)


  • 3. Data: 2011-06-18 18:54:58
    Temat: Re: Do osób znających instrukcje procesora Z80
    Od: Bronek Kozicki <b...@s...net>

    On 18/06/2011 19:13, Piotrek wrote:
    > Zastanawiające jest to, że mój tok rozumowania we wszystkich przypadkach
    > prowadzi do stwierdzenia będącego negacją stanu faktycznego. Wygląda na to, że
    > nie myślę źle, tylko moje rozumowanie opiera się na jakiejś błędnej
    > przesłance.


    ta przesłanka to założenie że implementacje odejmowania jest wrapperem
    dla dodawania. Tak nie jest; operacja odejmowania ustawia flagi tak, aby
    miały one sens dla odejmowania, a nie dla dodawania.


    B.


  • 4. Data: 2011-06-18 23:07:01
    Temat: Re: Do osób znających instrukcje procesora Z80
    Od: "Piotrek" <p...@p...onet.pl>


    > ta przesłanka to założenie że implementacje odejmowania jest wrapperem
    > dla dodawania. Tak nie jest; operacja odejmowania ustawia flagi tak, aby
    > miały one sens dla odejmowania, a nie dla dodawania.

    Tak podejrzewałem (chociaż z książek/manuali/stron, które do tej pory
    przejrzałem na ten temat, nijak to nie wynikało). Orientujesz się może jak
    flagi C i H są ustawiane w przypadku odejmowania, tzn. byłbyś w stanie podać
    mi analogiczne reguły? Sensowne wydaje się przyjęcie, że dla odejmowania
    flaga C jest ustawiana przy pożyczce z bitu nr 9 (faktycznie
    nieistniejącego), o ile operację odejmowania potraktujemy jako pisemne
    odejmowanie dwóch liczb binarnych. Niestety, nadal nie umiem podać
    analogicznej reguły dla półprzeniesienia-teoretycznie następowałoby ono w
    przypadku pożyczki z bitu 4, ale nie do końca mi to pasuje.



  • 5. Data: 2011-06-18 23:11:25
    Temat: Re: Do osób znających instrukcje procesora Z80
    Od: "Piotrek" <p...@p...onet.pl>


    > Sensowne wydaje się przyjęcie, że dla odejmowania
    > flaga C jest ustawiana przy pożyczce z bitu nr 9

    Miało być: bitu 9, czyli o numerze 8 licząc od 0



  • 6. Data: 2011-06-19 07:56:42
    Temat: Re: Do osób znających instrukcje procesora Z80
    Od: Bronek Kozicki <b...@s...net>

    On 19/06/2011 00:07, Piotrek wrote:
    >> ta przesłanka to założenie że implementacje odejmowania jest wrapperem
    >> dla dodawania. Tak nie jest; operacja odejmowania ustawia flagi tak, aby
    >> miały one sens dla odejmowania, a nie dla dodawania.
    >
    > Tak podejrzewałem (chociaż z książek/manuali/stron, które do tej pory
    > przejrzałem na ten temat, nijak to nie wynikało). Orientujesz się może jak
    > flagi C i H są ustawiane w przypadku odejmowania, tzn. byłbyś w stanie podać
    > mi analogiczne reguły? Sensowne wydaje się przyjęcie, że dla odejmowania

    niestety, podręcznik asemblera Z80 zgubiłem 20 lat temu ...


    B.


  • 7. Data: 2011-06-19 18:50:40
    Temat: Re: Do osób znających instrukcje procesora Z80
    Od: Mariusz Kruk <M...@e...eu.org>

    epsilon$ while read LINE; do echo \>"$LINE"; done < "Piotrek"
    >Załóżmy, że ograniczymy rozważania do operacji na rejestrach 8-bitowych. Moje
    >wątpliwości dotyczyły zachowania flag C (przeniesienia, ustawianej gdy nastąpi
    >przeniesienie z bitu 7, tzn. wynik nie zmieści się na 8 bitach) i H
    >(półprzeniesienia, ustawianej gdy dojdzie do przeniesienia z bitu 3 na 4).

    Niezależnie od tego, czy odejmowanie jest tłumaczone, czy nie,
    http://www.z80.info/z80code.htm twierdzi, że przy SUB:
    [...]
    C or carry flag 1 if answer <0 else 0
    Z or zero flag 1 if answer = 0 else 0
    P flag 1 if overflow in twos complement else 0
    S or sign flag 1 if 127<answer<256 else 0
    N flag 1
    H or half carry flag 1 if borrow from bit 4 else 0
    [...]
    A przy SBC:
    [...]
    C or carry flag 1 if <0 else 0
    Z or zero flag 1 if result = 0 else 0
    P flag 1 if TC >127 or <-128 else 0
    S or sign flag 1 if 127 < n <256 else 0
    N flag 1
    H or half carry flag 1 if borrow from bit 12 else 0
    [...]
    (w ostatniej linijce oczywisty błąd, powinno być "bit 4"; dalej jest
    wersja szesnastobitowa, w której powinno być o bicie dwunastym).

    >Rozpatrywane były następujące operacje:
    >
    >1) działanie 3 - 5 (w praktyce załadowanie pierwszej wartości do rejestru A i
    >wykonanie instrukcji SUB 5).
    >
    >Moim zdaniem nie dojdzie tu do półprzeniesienia, zdaniem mojego dyskutanta-tak.
    >Oto jak rozumowałem:
    >
    >3 - 5 to dla procesora de facto 3 + (-5), 3 to bitowo 00000011,
    >-5 to 11111011 (działamy w U2).
    >
    >Zapisując to jedno pod drugim i rachując pisemnie od prawej do lewej (od
    >najmłodszego bitu do najstarszego) i zakładając, że procesor liczy to tak
    >samo, dostaję kolejno:
    >
    >- na pozycji 0 sumę 1 + 1 -&gt; mamy przeniesienie z bitu 0 na 1
    >- na pozycji 1 sumę 1 + 1 + 1 (przeniesienie) -&gt; mamy przeniesienie z 1 na 2
    >- na pozycji 2 sumę 0 + 0 + 1 (przeniesienie) -&gt; brak przeniesienia z 2 na 3
    >
    >Ponieważ ostatnie działanie nie wygenerowało nowego przeniesienia, a dalej nie
    >mamy już sytuacji, w której sumowalibyśmy dwie jedynki, nie ma bata, żeby
    >wygenerowało nam się nowe przeniesienie, w szczególności przeniesienie z bitu
    >3 na 4. Zdaniem mojego dyskutanta jednak występuje. Gdzie tu błądzę?

    Najwyraźniej jednak nie ma zamiany na dodawanie, tylko jest od 00000011
    odjęcie 00000101. Wtedy jak najbardziej będziemy pożyczać od bitu
    trzeciego aż do przepełnienia.

    Reszta przypadków idzie analogicznie.

    >Zastanawiające jest to, że mój tok rozumowania we wszystkich przypadkach
    >prowadzi do stwierdzenia będącego negacją stanu faktycznego. Wygląda na to, że
    >nie myślę źle, tylko moje rozumowanie opiera się na jakiejś błędnej
    >przesłance.

    Czyżby jednak zamiana odejmowania na dodawanie nie była słusznym
    posunięciem?

    W każdym razie, http://www.z80.info/zip/z80cpu_um.pdf wcale nie mówi o
    zamianie odejmowania na dodawanie, a wręcz przeciwnie, pokazuje na
    przykład na stronie 78 odejmowanie i jego skutki dla sygnalizacji
    przepełnienia.

    --
    \------------------------/
    | K...@e...eu.org | http://www.nieruchomosci.pl/mieszkanie,38804171
    | http://epsilon.eu.org/ |
    /------------------------\


  • 8. Data: 2011-06-19 21:06:12
    Temat: Re: Do osób znających instrukcje procesora Z80
    Od: Artur Muszyński <a...@u...wytnijto.com.pl>

    W dniu 2011-06-19 01:07, Piotrek pisze:
    >> ta przesłanka to założenie że implementacje odejmowania jest wrapperem
    >> dla dodawania. Tak nie jest; operacja odejmowania ustawia flagi tak, aby
    >> miały one sens dla odejmowania, a nie dla dodawania.
    >
    > Tak podejrzewałem (chociaż z książek/manuali/stron, które do tej pory
    > przejrzałem na ten temat, nijak to nie wynikało). Orientujesz się może jak
    > flagi C i H są ustawiane w przypadku odejmowania, tzn. byłbyś w stanie podać
    > mi analogiczne reguły? Sensowne wydaje się przyjęcie, że dla odejmowania
    > flaga C jest ustawiana przy pożyczce z bitu nr 9 (faktycznie
    > nieistniejącego), o ile operację odejmowania potraktujemy jako pisemne
    > odejmowanie dwóch liczb binarnych. Niestety, nadal nie umiem podać
    > analogicznej reguły dla półprzeniesienia-teoretycznie następowałoby ono w
    > przypadku pożyczki z bitu 4, ale nie do końca mi to pasuje.

    Niewiele już pamiętam, ale wątpię, abym kiedykolwiek użył flagi H :-)
    Jeśli to ma być projekt zabawowy, to ja bym na twoim miejscu odpuścił
    sobie chwilowo ten problem.
    W kwestii przeniesienia, to zależy, co się czyta.
    Podstawowy schemat:
    http://en.wikipedia.org/wiki/Adder-subtractor
    wg mnie jest skopany pod tym względem, ale już tutaj:
    http://tams-www.informatik.uni-hamburg.de/applets/ha
    des/webdemos/20-arithmetic/40-addsub/add-sub.html
    widać, że C będzie ustawione w twoim przypadku, tak samo, jak zrobi ALU
    w Z80.
    PS: Oprócz książek, warto jednak trochę poeksperymentować - ZX Spin ma
    wbudowany assembler i debugger.

    artur

strony : [ 1 ]


Szukaj w grupach

Szukaj w grupach

Eksperci egospodarka.pl

1 1 1

Wpisz nazwę miasta, dla którego chcesz znaleźć jednostkę ZUS.

Wzory dokumentów

Bezpłatne wzory dokumentów i formularzy.
Wyszukaj i pobierz za darmo: