Kristoffer Eriksson
<5357>
· Text 891 · w8 · kommentar
1987-07-13 00:37
Ärende: DEC A / Flaggor
Man kan ju inte låta flaggorna återspegla innehållet i just A jämt.
Man kan vara intresserad i innehållet i andra register också,
som HL, eller resultatet av en operation typ CP som ju inte lämnar
resultatet någon stanns.
Sen är ju inte Z den enda flaggan som finns. Det finns t ex P/V-
flaggan som vid aritmetiska operationer indikerar overflow (som f ö
inte lagras i resultatets register, utan bara i flaggan) och vid
logiska får resultatets paritet, om den påverkas alls. N-flaggan
talar om huruvuda den senaste operationen som påverkade flaggan var
en addition eller subtraktion, vilket inte har något alls med
resultatet att göra.
Med detta vill jag visa att det finns anledning att låta varje
instruktion detaljreglera vad som händer med de olika flaggorna. Då
är det inte långt för CPU:ns konstruktörer att reglera Z-flaggan på
liknande sätt.
Vissa situationer då det inte finns någon anledning att ändra Z-
flaggans innehåll är rent uppenbara: hopp-instruktioner. Det vore
ju dumt att om Z avspeglar resultatet av en CP mellan t ex A=10 och
B=10 då Z blir sann, och ett hopp görs någonstanns, då återställa
Z till falsk pga att A<>0. Det skulle betyda att vill man använda
ett resultat till flera villkorliga hopp i rad, måste man göra
om operationen direkt före varje hopp (vilket även innebär att
registren måste ha kvar sina värden hela tiden).
Då är frågan: När bör flaggan påverkas? En svår fråga som varje
CPU-konstruktör får brottas med. Och det gäller även 6800-serien
(David nämnde 6809). Det som har betydelse för beslutet är vilka
fördelar det ger för programmeraren. De fördelar det ger att inte
låta alla instruktioner påverka flaggorna, är som jag nämnde att
flaggorna avspeglar resultatet av de för programmet intressanta
operationerna länge, och inte störs av ointressanta saker som RET,
så man inte måste upprepa viktiga test flera gånger, samt får
frihet att lägga testet en bit före dess effekt (JP/JR). Nyttan av
detta gav jag exempel på i förra inlägget.
Intressanta operationer är i synnerhet jämförelser: CP, och i andra
hand aritmetiska och logiska operationer. Vad som är intressant
varierar förstås med vilka flagga som avses.
Vad jag försöker förklara är att det inte är självklart att man
alltid vill att flaggorna ska avspegla den allra senast gjorda
operationen. Varför just ADD HL,ss inte påverkar Z-flaggan vet jag
inte, men den kompletteras fint av ADC som gör det. Därmed finns
det en additionsoperation som påverkar flaggan, och en som inte gör
det. I övrigt påverkas Z av de flesta operationer som påverkar
registren.
Faktum är att det inte varierar helt godtyckligt från instruktion
till instruktion vad som händer med flaggorna. Jag kan citera
början av en sammanfattande tabell:
S Z H P/V N C
ADD A,s; ADC A,s: ! ! ! V 0 !
SUB s; SBC A,s; CP s; NEG ! ! ! V 1 !
AND s ! ! 1 P 0 0
OR s; XOR s ! ! 0 P 0 0
INC s ! ! ! V 0 -
DEC s ! ! ! V 1 -
ADD dd,ss - - X - 0 !
ADC HL,ss ! ! X V 0 !
SBC HL,ss ! ! X V 1 !
P=Parity, V=Overflow, !=Enligt operationens resultat,
X=Odefinierat, -=Ej påverkad.
Iofs är väl Z80 en påbyggd 8080 (eller vad det var), men jag tror
inte man ska skylla alltför mycket konstigheter på det (dock kanske
ADD HL kontra ADC HL?). Man har lyckats stoppa in ganska mycket i
Z80 jämfört med övriga 8-bittars processorer från den tiden.
När det gäller processorns asymmetri, så har den väl en del att
göra med många instruktioner - få instruktionskoder och begränsat
utrymme på chippet...