Föreläsningsunderlag TSEA82 Datorteknik D TSEA57 Datorteknik I



Relevanta dokument
Föreläsningsanteckningar 2. Mikroprogrammering I

Föreläsningsanteckningar 3. Mikroprogrammering II

F2: Motorola Arkitektur. Assembler vs. Maskinkod Exekvering av instruktioner i Instruktionsformat MOVE instruktionen

7) Beskriv tre sätt att överföra parametrar mellan huvudprogram och subrutin.

Det finns en hemsida. Adressen är

Tentamen. Datorteknik Y, TSEA28

Programmering av Motorola TSIU02 Datorteknik

Tentamen. Datorteknik Y, TSEA28

Övning1 Datorteknik, HH vt12 - Talsystem, logik, minne, instruktioner, assembler

HF0010. Introduktionskurs i datateknik 1,5 hp

Elektroteknik MF1016 föreläsning 9 MF1017 föreläsning 7 Mikrodatorteknik

Tentamen Datorteknik D del 2, TSEA49

Tentamen. Datorteknik Y, TSEA28

A-del motsvarande KS1

Grunderna i stegkodsprogrammering

Datorsystem Laboration 2: Minnesmappade bussar

Tentamen. Datorteknik Y, TSEA28

Tentamen Datorteknik Y, TSEA28 Datum

Tentamen. Datorteknik Y, TSEA28

Digital- och datorteknik

Tentamen Datorteknik Y, TSEA28 Datum TER2, TER4, TERE Tid 14-18

F4: Assemblerprogrammering

Datorsystemteknik DAV A14 Föreläsning 1

3. Mikroprogrammering II

Tentamen. Datorteknik Y, TSEA28

Omtentamen i CDT204 - Datorarkitektur

Datormodell. Datorns uppgifter -Utföra program (instruktioner) Göra beräkningar på data Flytta data Interagera med omvärlden

Tentamen. Datorteknik Y, TSEA28

Tentamen (Exempel) Datorteknik Y, TSEA28

Föreläsning 3.1: Datastrukturer, en översikt

Tentamen. Datorteknik Y, TSEA28

Övningsuppgifterna i kapitel F avser FLIS-processorn, vars instruktioner och motsvarande koder definieras i INSTRUKTIONSLISTA FÖR FLISP.

Digital- och datorteknik

Mikroprogrammering I

Datorteknik. Tomas Nordström. Föreläsning 2. För utveckling av verksamhet, produkter och livskvalitet.

TENTAMEN Datorteknik (DO2005) D1/E1/Mek1/Ö1

Övningsuppgifter i Mikrodatorteknik 4p/5p

Digital- och datorteknik

Lösningsförslag till Tenta i Mikrodator

F8: Undantagshantering

Lösningar till tentamen i EIT070 Datorteknik

Programexempel för FLEX

TSEA28 Datorteknik Y (och U)

Föreläsningsanteckningar 4. Pipelining

Moment 2 Digital elektronik. Föreläsning Inbyggda system, introduktion

Stack och subrutiner Programmeringskonventionen

Provmoment: Ladokkod: Tentamen ges för: Tentamen TE111B El3. Namn: Personnummer: Tentamensdatum: Tid: 14:00-18:00.

Tenta i Digitalteknik

Tentamen. Datorteknik Y, TSEA28

SVAR TILL TENTAMEN I DATORSYSTEM, VT2013

0.1. INTRODUKTION Instruktionens opcode decodas till en språknivå som är förstålig för ALUn.

Föreläsning 6: Introduktion av listor

En Von Neumann-arkitektur ( Von Neumann-principen i föreläsning 1) innebär:

D/A- och A/D-omvandlarmodul MOD687-31

Konstruera en dator mha grindar och programmera denna Använda en modern microcontroller

CE_O3. Nios II. Inför lab nios2time

Övning1 Datorteknik, HH vt12 - Talsystem, logik, minne, instruktioner, assembler

Datorteknik TSIU02 Kursinformation

Digitalteknik EIT020. Lecture 15: Design av digitala kretsar

Vem är vem på kursen. Objektorienterad programvaruutveckling GU (DIT011) Kursbok Cay Horstmann: Big Java 3rd edition.

TSEA28 Datorteknik Y (och U)

System S. Datorarkitektur - en inledning. Organisation av datorsystem: olika abstraktionsnivåer. den mest abstrakta synen på systemet

Styrenheten styrsignalsekvenser programflödeskontroll

Tentamen (Exempel) Datorteknik Y, TSEA28

c a OP b Digitalteknik och Datorarkitektur 5hp ALU Design Principle 1 - Simplicity favors regularity add $15, $8, $11

Lösningsförslag till Tenta i Mikrodator

Datorteknik Övningsuppgifter

TSEA28 Datorteknik Y (och U)

Att använda pekare i. C-kod

General Purpose registers ALU I T H S V N Z C SREG. Antag att vi behöver skriva in talet 25 till register R18

F5: Högnivåprogrammering

F5: Högnivåprogrammering

Programmerbar logik. Kapitel 4

Lösningar till tentamen i EIT070 Datorteknik

Tentamen (Exempel) Datorteknik Y, TSEA28

Grundläggande datavetenskap, 4p

Villkorliga hopp: 9/26/2011. Dagens mål: Du ska kunna.. Villrorliga (Relativa) hopp - forts Arb s 140. LV5 Fo12. LV5 Fo12. Aktivera Kursens mål:

Datorsystemteknik DVGA03 Föreläsning 8

Digital- och datorteknik

LABORATION. Datorteknik Y

CE_O1. Nios II. Enkla assembler-instruktioner.

Datorteknik. Den digitala automaten. En dator måste kunna räkna! Register och bussanslutning

Per Holm Lågnivåprogrammering 2014/15 24 / 177. int och double = = 2, 147, 483, 647

TSEA28 Datorteknik Y (och U)

Minnet. Minne. Minns Man Minnet? Aktivera Kursens mål: LV3 Fo7. RAM-minnen: ROM PROM FLASH RWM. Primärminnen Sekundärminne Blockminne. Ext 15.

Dataminne I/O Stack 0x005D 0x3D SP low byte 0x005E 0x3E SP high byte

Digital- och datorteknik

Tentamen (Exempel) Datorteknik Y, TSEA28

Föreläsning 4: Poster

Utvärdering 2015 deltagare Voice Camp

Kursplanering för Mikrodatorteknik 4p/5p

Att komma igång med FirstClass (FC)!

Övning2 Datorteknik, HH vt12 - Programmering

Programräknaren visar alltid på nästa instruktion som skall utföras. Så fort en instruktion har hämtats så visar programräknaren på nästa instruktion.

Beskrivning av porthantering i mikroprocessorn SAM3U som används på vårt labkort SAM3U- EK.

Assemblerprogrammering del 3

Datorarkitekturer med operativsystem ERIK LARSSON

LV6 LV7. Aktivera Kursens mål:

Reducerad INSTRUKTIONSLISTA för FLIS-processorn

Transkript:

Föreläsningsunderlag TSEA82 Datorteknik D TSEA57 Datorteknik I Michael Josefsson Anders Nilsson (korrektur 2014, 2015) version 2015

Innehåll 0. Introduktion 7 0.1. Kurslitteratur.................................. 8 0.2. Övrig information............................... 8 0.3. Kursupplägg.................................. 8 1. Modelldatorn 9 1.1. Blockschema.................................. 9 Exempel................................. 10 1.2. Modelldatorns arkitektur........................... 12 1.2.1. Modelldatorns innehåll och arbetsgång................ 13 2. Instruktioner och adresseringsmoder 15 2.1. Ytterligare instruktioner............................ 15 2.1.1. Villkorsinstruktioner.......................... 15 Exempel................................. 16 2.1.2. Statusregister.............................. 16 2.1.3. Hoppinstruktioner........................... 16 2.2. Större adressrymd............................... 17 2.2.1. Större instruktionsbredd........................ 17 2.2.2. Variabelt instruktionsformat..................... 17 2.3. Ytterligare instruktioner............................ 18 2.4. Adresseringsmoder............................... 19 2.4.1. Underförstådd (implied) adressering................. 20 Exempel................................. 20 2.4.2. Omedelbar (immediate) adressering................. 20 Exempel................................. 20 2.4.3. Absolut (absolute) adressering.................... 21 Exempel................................. 21 2.4.4. Indirekt absolut (indirect absolute) adressering........... 21 Exempel................................. 21 2.4.5. Absolut indexerad (absolute indirect) adressering.......... 22 Exempel................................. 22 2.4.6. Relativ (relative) adressering..................... 22 Exempel................................. 22 2.5. Exempelprogram................................ 24 3. Subrutiner och stackar 25 3.1. Processorarkitektur............................... 25 3.1.1. Harvard/von Neumann........................ 25 Von Neumann............................. 25 3

Innehåll Harvard................................. 26 3.2. Subrutiner.................................... 27 3.2.1. Andra stackfunktioner......................... 28 3.2.2. Stackmodeller.............................. 28 1. Sist i minnet växer mot lägre adresser............. 29 2. Sist i minnet växer mot högre adresser............. 29 3. Mitt i minnet............................ 29 3.2.3. Vanliga stackfel............................. 29 Varning 1: Felaktig/ingen returaddress................ 30 Varning 2: Stack overflow....................... 30 3.3. Några riktiga processorer........................... 30 4. M68000 33 4.1. Instruktioner, instruktioner........................... 33 4.2. Motorola 68000 en verklig processor.................... 34 4.2.1. Registeruppsättning.......................... 35 4.2.2. Variabla operandstorlekar....................... 35 4.2.3. Minnesbredd.............................. 36 Exempel................................. 36 4.2.4. Automatisk teckenutvidgning (sign expansion)........... 37 4.3. Instruktioner 68000............................... 38 4.3.1. Instruktionen i datablad........................ 38 4.3.2. Assembler, äntligen........................... 39 4.3.3. Adresseringsmoder........................... 39 Register................................. 39 Omedelbar............................... 40 Exempel................................. 40 Absolut................................. 40 4.3.4. Exempelprogram I........................... 40 Exempel................................. 41 Exempel................................. 41 4.3.5. Ytterligare adresseringsmoder..................... 42 Indexerad (Motorola: Register Indirect)............... 42 Indexerad med förskjutning...................... 42 Indexerad med postinkrement..................... 43...och samma med predekrement................... 43 4.3.6. Exempelprogram II........................... 43 Exempel................................. 43 Register indirect with index and displacement............ 44 4.4. Subrutiner i 68000............................... 44 Exempel................................. 44 4.4.1. Något att fundera över......................... 47 4.5. Avbrott, i allmänhet.............................. 48 4.5.1. Vem avbröt mig?............................ 49 Pollning................................. 49 Daisy-chain............................... 50 4.6. Avbrott i 68000................................. 50 4.6.1. Avbrott eller inte avbrott........................ 52 4

Innehåll 5. Binär aritmetik I 55 5.1. Talbaser..................................... 55 5.2. Addition..................................... 56 Exempel................................. 57 Exempel................................. 57 5.3. Talrepresentationer............................... 58 Exempel................................. 58 5.4. Basen 2 10.................................... 59 Exempel................................. 59 5.5. Höger- och vänsterskift............................. 59 5.6. Omvandling från binär till decimal form och tvärtom............ 60 Exempel................................. 60 5.7. Hexadecimal representation.......................... 61 5.7.1. Omvandling binär till hexadecimal form............... 62 Exempel................................. 62 5.7.2. Olika skrivsätt............................. 62 5.7.3. Omvandling hexadecimal till decimal form.............. 62 Exempel................................. 63 5.8. Negativa binära tal............................... 63 5.8.1. Tecken-belopprepresentation..................... 63 Exempel................................. 63 Exempel................................. 64 5.8.2. 1-komplement.............................. 65 Exempel................................. 65 5.8.3. 2-komplement.............................. 66 Exempel................................. 67 Två anmärkningar........................... 67 Exempel................................. 67 5.9. Enkla operationer. Addition och skift..................... 68 5.10. Ett hjälpmedel: cirkulärgrafen......................... 69 Exempel................................. 69 5.10.1. Spill................................... 69 5.11. Hårdvara.................................... 70 6. D/A- och A/D-omvandlare 73 6.1. Inledning.................................... 73 6.2. D/A-omvandlare................................ 73 6.2.1. Omvandlare med resistorstege..................... 74 6.2.2. Belastningsimpedansens inverkan................... 75 6.2.3. Felkällor................................. 75 6.3. A/D-omvandlare................................ 76 6.3.1. Flash-omvandlaren........................... 77 6.3.2. Approximerande omvandlare..................... 77 6.3.3. Omvandlare med successiv approximation.............. 77 6.3.4. Sample & Hold............................. 79 Exempel................................. 79 6.3.5. Differentiella ingångar......................... 81 6.3.6. Felkällor................................. 81 5

Innehåll 7. Binär aritmetik II multiplikation 87 7.1. Multiplikation snitsigare metod...................... 90 Matematisk beskrivning av metoden................. 90 7.2. Men tvåkomplement då?............................ 92 7.2.1. Utökat talområde............................ 92 Exempel................................. 92 7.2.2. Spillkompensering av (a + b)/2.................... 93 Metod 1 Med utökat talområde.................. 93 Exempel................................. 93 Metod 2 Utan utökat talområde.................. 94 Exempel................................. 94 7.3. Robertsons algoritm.............................. 94 Exempel................................. 95 A. Robertsons algoritm 97 Exempel................................. 98 Metod 2 genom användning av spillflaggan............ 98 Exempel................................. 98 Exempel................................. 99 6

0. Introduktion I denna föreläsning bl. a.: presentation av kursen, modelldatorn, algoritm, flödesschema, operationer, instruktioner, instruktionsformat, register, minne, programmerarmodell. Välkomna! Jag hoppas att det här kommer att bli en nyttig och rolig kurs. Det är inte varje dag man får möjlighet att titta in under skalet på en dator och det är definitivt inte varje dag (eller kurs heller för den delen) man tillåts studera exakt hur digitalteknik och datorteknik hör ihop. Detta är första delen av ett större kurspaket som fortsätter med TSEA83, Datorkonstruktion och på sätt och vis avslutas i projektkursen TSEA29 Konstruktion med mikrodatorer. Tidigare har de två första delarna varit innehållna i en egen kurs men fortsättningskursens prägel, att verkligen konstruera en dator, motiverar nuvarande uppdelning. För att få ut största möjliga nöje ur kursen måste man ha sin digitalteknik i ganska fräscht minne. Den är grunden och utan den kommer vissa delar av den här kursen att kanske verka svårare än det egentligen är. Därmed inte sagt att man måste vara guru på Karnaughdiagram. Inte ett enda sånt kommer vi att behandla! Speciellt inför avsnitten med binära koder, binär aritmetik och senare också mikroprogrammering kommer vi att vara betjänta av digitalteknikkunskaper. Om du känner på dig att du inte har full koll på detta rekommenderas varmt att du läser motsvarande kapitel i digitalteknikboken när vi kommer till dessa områden. Vart leder allt det här då? Ja, till exempel bör du, efter genomgången kurs, kunna avgöra om detta är ett lämpligt datorsystem för kommande projektkurser: Atmel 8-bit microcontroller ATmega16 16K Bytes of In-System Self-Programmable Flash 1K Byte Internal SRAM 512 Bytes EEPROM Up to 16 MIPS Throughput at 16 MHz On-chip 2-cycle Multiplier Three counter/timers Four PWM channels 8-channel, 10-bit ADC Programmable Serial USART Two-wire Serial Interface Master/Slace SPI Serial Interface 7

0. Introduktion eller finns det några argument emot detta? Under kursens gång kommer vi beröra olika aspekter på kompromisser som konstruktörerna av en sådan mikrokontroller också tvingats göra. 0.1. Kurslitteratur Den officiella kurslitteraturen utgörs av Alan Clements The Principles of Computer Hardware. Den återfinns i bokhandeln. Till kursen hör också labhandledningar, samt det som du håller i handen just nu, det så kallade föreläsningsunderlaget. 0.2. Övrig information Kursen har en egen hemsida. Den finns vid http://www.isy.liu.se/edu/kurs/tsea82/. Där ligger upp nogrannare planering, rekommenderad läsning, diverse sista-minuten-tips osv. Eventuellt kompletterande material som delas ut på föreläsningarna återfinns också i kursens kursfack, beläget vid Datortekniks (ISY/DA) studentinformationstavla. 0.3. Kursupplägg Kursen innehåller åtta föreläsningar och obligatoriska laborationer samt laborationsförberedande lektioner. Labbarna börjar rätt tidigt så de första fyra-fem föreläsningarna är speciellt viktiga. Det känns egendomligt att rekommendera vissa föreläsningar på bekostnad av andra. Men så är det: De första är viktigast inför laborationerna. Det ser alltså ut så här, i denna läsperiod: 8 st Föreläsningar Le 1 Huvudsakligen labförberedande övningar (dvs läs labhandledningen innan). Lab 1 Infraröd länk Lab 2 I/O-programmering, a.k.a. Morselabben Lab 3 Digitalur Lab 4 Spel Som påpekats kommer första labben tidigt, så det är intensivt med föreläsningar till en början. Man måste anmäla sig till labbarna. Det görs elektroniskt och mail kommer ut med mer information om det. Vi tänker att man lär sig bättre om ämnet blir belyst från flera håll. Att det är nödvändigt med andras åsikter och synpunkter även om dom har fel! Därför innehåller hemsidan en del bredvidläsning, länkar till närliggande områden osv. Dessa ingår inte i kursen per se. Men det är förrädiskt att anta att kursen bara går ut på att resultera i ett antal avklarade labbar. Huvudpoängen är ju faktiskt att den ska resultera i kunskaper, inte bara lösa bitar av fakta staplade ovanpå varann. Man måste se och begripa relationen mellan olika fakta och dessutom få en överblick över helheten. 8

2. Instruktioner och adresseringsmoder I denna föreläsning: villkorsinstruktioner, statusflaggor, statusregister, hoppinstruktioner, ytterligare instruktionsformat, adresseringsmoder: underförstådd, omedelbar, absolut, indirekt, indexerad och relativ. 2.1. Ytterligare instruktioner Om man försöker programmera något med den instruktionsrepertoar som presenterades förra gången märker man snart att det inte går nåt vidare. Processorn är alldeles för liten och för enkel för att kunna användas till nåt egentligt nyttigt. Idag ska vi öka på innehållet i processorn något, så att den faktiskt går att använda till något. Det är framförallt på tre områden processorn måste hyfsas till: Först och främst saknas det instruktioner. Det borde finnas en instruktion som laddar konstanter. Vi har antagit att Gud på nåt sätt placerat konstanterna vi behöver på de rätta ställena. Vi kan ju inte i allmänhet i alla fall förlita oss på gudomlig intervention. Med 8-bitars programräknare kan man adressera 256 adresser, dvs ett program på som mest 256 rader kod. Det kan räcka för enklare tillämpningar men duger inte för WoW. Vi måste lösa detta problem. I modelldatorn kunde vi utföra villkorliga hopp om AR > 0. Det är bra. Villkorliga hopp är en nödvändighet för att kunna programmera beslut. Men ofta är villkoret AR > 0 inte det bästa. Vi ska lägga till ett antal ytterligare villkor. 2.1.1. Villkorsinstruktioner Vi betar av listan bakifrån och börjar med att lägga till fler villkor. Hoppinstruktionen kikar just nu på AR för att avgöra om hopp ska ske eller ej. Utan närmare förklaring inför vi här fyra ytterligare villkor med medföljande instruktioner. Om villkoren uppfyllts eller inte kan man läsa av från speciella vippor i processorn, som vi också får lägga till. Dessa vippor brukar kallas flaggor och signalerar olika tillstånd i processorn: 15

2. Instruktioner och adresseringsmoder De sista kanske behöver ett förtydligande? Exempel Addera 6 + 14 med användning av fyrabitars ord! 0110 = 6 + 1110 = 14 0100 = 4! Hallå där, det stämmer ju inte! Något är skumt här... (Talområdet överskreds och information om detta finns i minnesbiten.) 2.1.2. Statusregister För att hålla ordning på dessa fyra bitar brukar man lägga dom i ett villkors- eller statusregister, SR, även kallat CCR (Conditon Code Register) eller PSW (Program Status Word). 2.1.3. Hoppinstruktioner Nu kan vi med statusflaggorna införa ytterligare hoppinstruktioner JMPZ Hopp om senaste resultat = 0, dvs om Z-flaggan = 1. 16

2.2. Större adressrymd JMPC Hopp om minnessiffra finns, dvs om C-flaggan = 1. JMPN Hopp om senaste resultat < 0, dvs om N-flaggan = 1. JMPV Hopp om senaste resultat gav spill, dvs om V-flaggan = 1. Dessa nya villkor ger oss betydligt vettigare möjligheter att utföra hopp än JMPP. Samtliga flaggor antar sina värden för varje instruktion som körts. 2.2. Större adressrymd Nästa steg är att lägga till en större adressrymd och faktiskt därmed samtidigt möjliggöra fler instruktioner. Vi såg förra gången att opkoden innehöll både operation och operand i samma 8-bitars fält. Redan där kan man se antydan till en metod att erhålla större adressrymd: Gör ordet bredare! 2.2.1. Större instruktionsbredd Med bredare opkod kan enkelt större adressrymd erhållas. En fullt möjlig väg enkel och snabb. Men det visar sig finnas följdeffekter till detta angreppssätt som inte är attraktiva just nu: det äter resurser i form av digitalteknikkomponenter. Med bredare instruktion måste även IR (instruktionsregistret) breddas, minnet breddas mm. Vi är snåla för tillfället och letar en alternativ lösning. 2.2.2. Variabelt instruktionsformat Mindre resurskrävande är variabelt instruktionsformat. Vi inför tre olika instruktionsformat. Kan vi inte ta instruktionen på bredden enligt ovan får vi väl ta den på höjden då: 17

2. Instruktioner och adresseringsmoder 2.3. Ytterligare instruktioner Fler instruktioner slutligen. Våra nuvarande åtta instruktioner är lite handikappande. Vi måste ha fler. Det visar sig att de normalt sönderfaller i några bestämda kategorier: De instruktioner som kanske är lite krångligare än andra är de logiska. Här finner vi tre skift-instruktioner och några bitvis logiska instruktioner. Med detta som ledning presenteras här en mer komplett lista utökad till 20 mer sannolika instruktioner 1 1 Listan än inte färdig på något sätt. Den kan minskas eller utökas beroende på vad man som konstruktör är ute efter för profil på sin processor. 18

2.4. Adresseringsmoder Instruktion Verkan Status Antal bytes Antal cykler N Z C V LDA addr AR := M(addr) * * - 0 2-3 2-3 STA addr M(addr) := AR - - - 0 2-3 2-3 ADC addr AR := AR + M(addr) + C * * * * 2-3 4-5 SBC addr AR := AR M(addr) C * * * * 2-3 2-3 INC AR := AR + 1 * * * * 1 1 DEC AR := AR 1 * * * * 1 1 CMP addr AR M(addr) * * * * 2-3 3-4 CLC C := 0 0 0 0 0 1 1 ASR AR := AR/2 * * * - 1 2 ASL AR := AR 2 * * * * 1 2 LSR logiskt högerskift av AR 0 * * - 1 2 AND addr AR := AR and M(addr) * * - 0 2-3 4-5 OR addr AR := AR or M(addr) * * - 0 2-3 4-5 JMP addr P C := addr - - - - 2-3 3-4 JMPN addr P C := addr om N = 1 - - - - 2-3 3-4 JMPZ addr P C := addr om Z = 1 - - - - 2-3 3-4 JMPC addr P C := addr om C = 1 - - - - 2-3 3-4 JMPV addr P C := addr om V = 1 - - - - 2-3 3-4 IN AR := IN * * - 0 1 1 OUT UT := AR - - - 0 1 1 Symbolerna för statusflaggorna i tabellen skall tolkas enligt: - = påverkas inte, * = påverkas, 1 eller 0 = flaggan tvingas till detta tillstånd. Kolumnen Antal cykler anger för en viss realisering av denna arkitektur det antal klockcykler instruktionen tar i anspråk. Här underförstås att de enklaste instruktionerna kan både hämtas och exekveras på en klockcykel. Detta visar sig senare vara en rätt optimistisk uppskattning det tar normalt några klockcykler redan för att hämta en instruktion men duger i våra hittills lätt oprecisa termer. Skall man vara noggrann anger kolumnen alltså det antal maskincykler som respektive instruktion kräver. En maskincykel är en abstrahering på högre nivå där man inte bryr sig om exkat hur hårdvaran löser det. Med maskincykelbegreppet ser vi att de enklaste instruktionerna tar en sådan cykel, medan de instruktioner som också behöver ett argument tar ytterligare en eller två cykler beroende på om argumentet är kort (en byte) eller långt (två byte). Med så här många instruktioner behöver vi fler än våra tidigare tre bitar av opkoden för att peka ut instruktionen. Fyra bitar ger 16 instruktioner och fem bitar 32 instruktioner. Tydligen behöver vi i det här fallet 5 bitar av opkoden för att peka ut en instruktion. 2.4. Adresseringsmoder Nu kommer det krångliga: Hur ska man kunna peka ut operander? Exempel på olika rimliga sätt är: 19

2. Instruktioner och adresseringsmoder LDA 20 som anger adressen (20) till det datum vi vill ladda LDA #20 som laddar konstanten 20 till AR Det är en väsentlig skillnad mellan dessa. Den första är absolut adressering och den sista exempel på omedelbar adressering (som förvirrande nog också kallas direkt adressering ibland). Lägg märke till vad 20 är i de båda fallen, en adress eller ett faktiskt data. Utöver dessa två ganska vanliga sätt att peka ut operanden finns ytterligare några stycken vi måste lära oss. Alla adresseringsmoder leder fram till att den s.k. effektiva adressen, EA, beräknas. Den effektiva adressen är alltså den adress som är resultatet när adresseringsmoden avkodats/vecklats upp så mycket som möjligt. Totalt ska vi nu lära oss 6 stycken grundläggande adresseringsmoder. Lägg speciellt märke till vilken EA som blir resultatet i varje enskilt fall. 2.4.1. Underförstådd (implied) adressering Exempel INC 2.4.2. Omedelbar (immediate) adressering Exempel LDA #20 20

2.4. Adresseringsmoder 2.4.3. Absolut (absolute) adressering Exempel LDA 20 2.4.4. Indirekt absolut (indirect absolute) adressering Exempel JMP (20) 21

2. Instruktioner och adresseringsmoder 2.4.5. Absolut indexerad (absolute indirect) adressering Exempel LDA 20,X Denna instruktion kräver ytterligare hårdvara för att kunna verkställas. Vi utökar processorn med ett indexregister, X samt några instruktioner för att kunna hantera detta speciella register: 2.4.6. Relativ (relative) adressering Exempel BRA 39 22

2.4. Adresseringsmoder Denna adresseringsmod används ofta för relativa hopp. Kod som enbart hoppar med relativa hopp är relokerbar dvs den kan placeras var som helst i minnet: 23

2. Instruktioner och adresseringsmoder 2.5. Exempelprogram Bara för att visa på att vi inte är helt ute och cyklar kommer här ett litet program som du kan prova att nästla upp. Exakt vad gör programmet egentligen 2? LDX $200 DEX LOOP LDA ($201),X STA ($203),X DEX BNE LOOP LDA $200 CLC ADC $203 STA $203 adress $200 $201 $202 $203 $204 $205 $206 $207 $208 $209 $20A minne adress $20B $20C $20D $20E $20F $210 $211 $212 $213 $214 $215 minne adress $216 $217 $218 $219 $21A $21B $21C $21D $21E $21F $220 minne 2 Tips:!vläjs tu atsil ud råf 402$ 302$ nem sserdatrats ne 202$ 102$,latna tte rehllåhenni 002$ 24

3. Subrutiner och stackar I denna föreläsning: processorarkitekturvarianter, Harvard, von Neumann, subrutiner, returstack, stackmodeller, några vanliga felkällor 3.1. Processorarkitektur Vår mikroprocessor håller på att ta form. En processor med det utseende vi arbetade fram under förra föreläsningen är fullt tillräcklig för en hel massa uppgifter. Den gick ju till och med att programmera till slut. Faktum är att 90% av alla processorer som tillverkas idag ser ut ungefär som den. Det finns variationer i instruktionsuppsättningen förstås, men den sortens processorer med s k ackumulatorarkitektur är de förhärskande. En så enkel processor kanske inte sitter i din PC på skrivbordet men ytterst få av alla tillverkade processorer finns på skrivborden. De allra flesta sitter inbyggda i någon apparat: det finns säkert flera i din TV, tvättmaskin, torktumlare, klocka, en i varje tangentbord, mobiltelefonen har flera osv. Och med stor säkerhet skulle vi känna igen dessa processorers instruktionsuppsättning och allmänna upplägg. De har register vi känner igen PC, IR, AR osv de har säkert åtminstone en del av adresseringsmoderna, men kanske inte alla. Men flera av adresseringsmoderna är så fundamentala att de inte går att komma förbi om vi ska kunna peka ut operanderna på ett effektivt sätt. 3.1.1. Harvard/von Neumann Innan vi ska avsluta beskrivningen av vår processor kan det vara intressant att kika lite på de två stora arkitekturvarianter som finns, Harvard- och Von Neumann-arkitekturerna. I huvudsak kan en processor klassas utefter vilken arkitektur den följer. Numera har utvecklingen dock gått så många och varierande spår att den enkla uppdelningen kanske inte gäller helt och hållet för varje processor, man kan ha lånat praktiska delar ur den konkurrerande arkitekturmodellen. Von Neumann John Von Neumann var en ungerskfödd matematiker som var verksam i USA från 30-talet och fram till sin död 1957. Han var bland annat involverad i utvecklingen av vätebomben och var mycket medveten om den mycket stora mängd simuleringar och beräkningar som måste till stånd för att utveckla den. Av en slump kom han i kontakt med andra inom amerikanska försvaret som ville automatisera beräkningar. Han började omedelbart skissa på en beräkningsmaskin med arkitektur där bland annat program och data delade på samma minne. 25

3. Subrutiner och stackar Arkitekturen har stått emot tidens tand mycket väl. Det är känt att den är behäftad med åtminstone en stor nackdel, den prestandanedsättande s k Von Neumannska flaskhalsen som är ett resultat av att både program och data delar på den tillgängliga bandbredden mot minnet: Man kan inte hämta programinstruktioner och data samtidigt utan måste utföra dessa operationer efter varann. Även om flaskhalsen är prestandanedsättande är inte läget sådant att man inte kan göra något åt det. Till exempel med hälp av förhämtning av flera instruktioner när tillfälle ges. Mer om detta kommer vi att nämna vid den speciella försläsningen om alternativa arkitekturer. Harvard Samtidigt med Von Neumann höll ett forskarlag på Harvard att utveckla en beräkningsapparat (Harvard Mk I), men längs ett annat spår. Man separerade program- och dataminnet. Denna uppdelning ger möjlighet att läsa från programminnet samtidigt med läsningar/skrivningar mot dataminnet. Man kommer då bort från att både program och data belastar samma buss. I och med att man kan utföra minnesoperationer samtidigt kan man tänka sig att man erhåller dubbla prestanda med denna arkitektur jämfört med von neumann-arkitekturen. Fördelar och nackdelar existerar med båda arkitekturerna. Exempelvis kan ju inte den ortodoxa harvardarkitekturen skriva till sitt egna program något vi ofta betraktar som en självklarhet. I vissa tillämpningar är harvardmodellen mer lämplig. I inbyggda system exempelvis, där processorn programmeras en gång för alla och aldrig mer. Då kan harvardarkitekturen vara lämplig och det är ingen slump att många mikrokontrollers är uppbyggd enligt denna. 26

3.2. Subrutiner 3.2. Subrutiner Vår dator kan göra mycket men det finns en finess som bara måste med: Subrutiner. Det är utrymmesbesparande att inte repetera kod utan att istället anropa den från olika ställen. Det färdiga programmet tar mindre plats i programminnet, men den riktigt stora vinsten är att subrutinerna ger stor hjälp att strukturera programmet på ett bra sätt. Till detta kommer att eventuella fel bara behöver rättas på ett ställe, inte på flera. Alla riktiga assemblerprogram använder subrutrutiner. För att kunna använda subrutiner måste vi konstruera några ytterligare instruktioner. Två är uppenbara: JSR addr, hopp och RTS, återhopp. Den första (Jump to SubRoutine) utför det speciella hoppet och den andra (ReTurn from Subroutine) hanterar återhoppet till det anropande programstycket. Följer vi ett programflöde märker vi snart att det kan vara olika återhoppsadress varje gång (beroende på varifrån JSR sker). Vi måste hålla ordning på denna återhoppsadress. Det är precis det återhoppsinstruktionen RTS utför. RTS-instruktionen är något egendomlig. Betrakta följande program: Man ser att det är praktiskt att kunna nästla subrutinanrop, dvs låta subrutiner ha möjligheten att anropa subrutiner i sin tur. Detta medför att vi måste hålla ordning på mer än en återhoppsadress. Lite begrundande ger att vi återhoppar i omvänd ordning till rutinanropen. Hittills har vi löst alla processorns tillkortakommanden genom att lägga till ytterligare register (har ni tänkt på det?). Kan det rädda oss även här? I och med att vi återhoppar i omvänd ordning till rutinanropen duger en stack för att lagra våra återhoppsadresser: 27

3. Subrutiner och stackar Enklast är att lägga stacken i det vanliga (data)minnet, då räcker det att processorn förses med ett register som pekar ut senaste återhoppsadress som alltså ligger i minnet. Ett processorregister, stackpekaren, SP, införs med denna uppgift. Eftersom det i princip bara är JSR och RTS som använder SP kan vi helt sonika bestämma att dessa instruktioner, och inga andra, automatiskt petar på SP så att allt blir bra. 1 En fråga som uppstår är om man ska låta SP peka på sist lagrade returaddress eller nästa användbara minnesposition? Det spelar i praktiken ingen roll, så länge man vet vad man gör och parar JSR med motsvarande RTS. Det är under alla förhållanden inget vi som användare kan göra något åt. Processortillverkaren har valt ett sätt åt oss. Mekanismen vid JSR och RTS blir således 2 : JSR addr RTS M(SP):=PC, PC:=addr, SP:=SP-1 SP:=SP+1, PC:=M(SP) eller JSR addr RTS SP:=SP-1, M(SP):=PC, PC:=addr, PC:=M(SP), SP:=SP+1 Den uppmärksamme läsaren märker nu att ovanstående beskrivning förutsätter att PC inte pekar på den assemblerrad som innehåller JSR utan på den närmast efter. Om PC pekade på JSR skulle ju programflödet vid RTS styras tillbaka till det hopp som just gjordes, vilket alltså skulle göras igen och igen, och igen osv. 3 3.2.1. Andra stackfunktioner Förutom att använda stacken för att lagra återhoppsadresser kan man nyttja stacken för att snabbt spara undan annan data. Vi inför för detta två nya instruktioner PHA, PusH Accumulator, och PLA, PulL Accumulator. Den senare kallas även ofta för POP, funktionen är dock densamma. Adresseringsmoden är tydligen underförstådd (implied) eftersom inga operander behövs. Instruktion PHA PLA Innebörd M(SP):=AR, SP:=SP-1 SP:=SP+1, AR:=M(SP) 3.2.2. Stackmodeller Hur implementerar vi nu denna stack? Det finns flera lösningar, olika stackmodeller: 1 Exakt hur det går till kommer vi till senare när vi studerar mikroprogrammering. 2 Här antas i båda fallen att stacken växer mot mindre adresser. Det är vanligtvis så stackarna (!) är gjorda, men det finns naturligtvis inget som hindrar att de kan tillverkas så att de växer mot större adresser. 3 Att det trots detta inte står PC+1 eller något sådant beror dels på att det inte är säkert att nästa instruktion finns på nästa byte efter JSR, dels på att processorn i sin hämt- och avkodningsfas själv petar på PC så att den efter instruktionen faktiskt är uppräknad till ett korrekt väre. Vi kommer till det i kapitlen om mikrokod. 28

3.2. Subrutiner 1. Sist i minnet växer mot lägre adresser Här har stacken placerats sist i det tillgängliga minnet och tillåts växa mot lägre adresser. En fördel med denna placering är att stacken inte har en förutbestämd största storlek. En förutbestämd storlek på stacken skulle omedelbart sätta restriktioner på antalet nästlade subrutinanrop processorn klarar av 4 eller ett tak på antalet värden som kan lagras på stacken med PHA-instruktionen. 2. Sist i minnet växer mot högre adresser Stacken tillåts här växa mot högre adresser och beroende på var stackpekaren initieras kan detta vara en tillräckligt stor stack eller inte! 3. Mitt i minnet En generell implementation av en stack tillåter naturligtvis att stacken placeras var som helst i minnet. Detta kan vara en fördel i och med att det är flexibelt men innebär därmed inte att det är avgjort bättre än de tidigare. 3.2.3. Vanliga stackfel Förutom att vara oerhört praktiska, är subrutiner en källa till irritation och emellanåt stor förvåning även hos erfarna programmerare. Eftersom stackhanteringen sker automatiskt, utom synhåll från programmeraren, är det lätt att missa följdverkningarna. Det kan alltså vara på sin plats att varna för ett par vanliga fel som är relaterade till stackhantering. Fel som vi naturligtvis aldrig kommer att göra, eller? 4 Varför bara restriktioner på antalet nästlade anrop och inte totala antalet subrutinanrop? 29

3. Subrutiner och stackar Varning 1: Felaktig/ingen returaddress Varning 2: Stack overflow Om fel uppstått kan man överväga om stacken måste rensas. I varje fall bör stackpekaren initieras på nytt så att den inte pekar utanför stackens tilldelade område. Det var allt nämnvärt om stack och subrutiner. Läs mer i kursboken om det inte är kristallklart. På labbarna kommer subrutiner att användas, mycket blir enklare då. Försök inte snedda över kursen genom att hoppa över subrutinerna. 3.3. Några riktiga processorer Nu är det också dags att kolla hur ett antal riktiga processorer ser ut. Titta på läsanvisningarna på kurshemsidan för några datablad. 30

3.3. Några riktiga processorer Där finns ett datablad för Motorola 68000, den som laborationerna baseras på 5, men de övriga är bara för ren nöjesläsning. Kolla speciellt på saker som ordbredd, minnesmängd, adressrymd, registeruppsättning, instruktionsuppsättning m m. 5 För de som redan kan det här: Labbarna körs på egentligen på 68008 så programmeraromgivningen är densamma). 31

4. M68000 I denna föreläsning bl. a.: Motorola 68000. Interna register, operandstorlekar, minnesbredd, assembler, adresseringsmoder, subrutiner, avbrott, pollning, trap, avbrottsnivåer. 4.1. Instruktioner, instruktioner... Vi har i de första föreläsningarna ägnat vår uppmärksamhet åt en hypotetisk modelldator och sett hur den fungerar. Vi har sett hur programinstruktionerna pekas ut och hämtas in till instruktionsregistret, hur eller i varje fall att instruktionen därefter avkodas och körs, allt enligt modellen hämta avkoda utför. Beroende på vad vi vill åstadkomma med processorn har vi också sett att vi, vid konstruktionen av den, har stora möjligheter att välja instruktionsrepertoar. I vårt fall föreslog vi följande instruktionslista: Instruktion Verkan Status Antal bytes N Z C V LDA addr AR := M(addr) * * - 0 2-3 STA addr M(addr) := AR - - - 0 2-3 ADD addr AR := AR + M(addr) * * * * 2-3 SUB addr AR := AR M(addr) * * * * 2-3 INCA AR := AR + 1 * * * * 1 DECA AR := AR 1 * * * * 1 CMP addr AR M(addr) * * * * 2-3 CLRA AR := 0 0 1 0 0 1 ASRA AR := AR/2 * * * - 1 ASLA AR := AR 2 * * * * 1 LSRA logiskt högerskift av AR 0 * * - 1 AND addr AR := AR and M(addr) * * - 0 2-3 OR addr AR := AR or M(addr) * * - 0 2-3 JMP addr P C := addr - - - - 2-3 JMPN addr P C := addr om N = 1 - - - - 2-3 JMPZ addr P C := addr om Z = 1 - - - - 2-3 JMPC addr P C := addr om C = 1 - - - - 2-3 JMPV addr P C := addr om V = 1 - - - - 2-3 IN AR := IN * * - 0 1 OUT UT := AR - - - 0 1 Detta är vår assemblerarsenal att lösa programmeringsuppgifterna med. Är instruktionerna väl valda och den underliggande arkitekturen förnuftigt gjord kan hela processorn exekvera vår assemblerkod mycket effektivt har vi dabbat oss med endera, kanske den blir en högst medioker apparat som inte gör nån större nytta. Det är väl fullt klart nu att det är svårt, till mycket svårt, att konstruera en processor från grunden utan att ha tänkt till ordentligt innan. 33

4. M68000 Då är det knappast en överraskning att andra tänkt klart åt oss och bara lämnat en programmerarmodell åt oss att sätta oss in i. Som exempel på hur man gjort ska vi ägna oss åt Motorolas M68000. 4.2. Motorola 68000 en verklig processor M68000, även kallad 68k, är en efterföljare till Motorolas tidigare mikroprocessor M6800 som mer liknade den ackumulatorarkitektur vi hittills studerat. Man ser att 6800 är en s.k. 8-bitars processor eftersom ackumulatorbredden är 8-bitar. Av praktiska skäl är andra register 16-bitar breda: Det är åtminstone dubbelt så snabbt att peka ut ett datum i minnet med en full 16-bitarsaddress än att peka ut den med två på varandra följande 8-bitars adressvärden. Ett knep konstruktörerna dessutom använt är att inte bara ha en ackumulator utan faktiskt två. På detta sätt hoppas man kunna hålla mellanlagragringsvärden kvar i processorn för nästa användning istället för att lämpa ut dom till minnet och sedan behöva ta in dom igen efter en stund. Det är rätt smart och det visar lite på hur ingenjörerna på Motorola tänkte då de efter ett par års framgång med 6800 tog sig an problemet att konstruera Motorolas nästa generations mikroprocessor den förväntans tystnad! inte mindre än 16-bitars 68000! På sin tid, 1977, var processorn 68000 ungefär vad man som bäst kunde tillverka med någon ekonomisk framgång. Det var på den tiden oerhört svårt att klämma in alla transistorer på den lilla millimeterstora kiselplattan som fanns till förfogande. Åtminstone om man ville ha rimligt stor del av de tillverkade som faktiskt fungerade efteråt. Som av en tanke fast dom säger att det är en slump innehåller 68000 just 68 tusen transistorer! Nuförtiden klämmer man in miljoner och åter miljoner transistorer i en vanlig processor 1 men 68000 var precis på gränsen till det möjliga 1977. Två ackumulatorer i 6800 visade lite på hur Motorolafolket tänkte. Om man tyckte att två ackumulatorer var bättre än en vad vore då bättre ännu flera ackumulatorer? Inte mycket tydligen, för det var precis vad man gjorde. Inte mindre än 8 ackumulatorer fick man plats med. Varje enda av dessa kan göra vad man förväntar sig av en ackumulator (ADD/SUB/MULT/logiska operationer osv). Men en processor består inte av ackumulatorer allena. Åtminstone en stackpekare behövs. Kanske vill programmeraren ha fler stackar? Låt honom isåfall ha det, tänkte man. Vill man ha ett eller flera indexregister? Låt honom ha det. Var generell. Man var så generell att man tillät inte mindre än 8 stycken adressregister för just denna sorts pekare 1 Sådan som sitter i en vanlig dator d v s som exempelvis Intel, Amd och IBM tillverkar. 34

4.2. Motorola 68000 en verklig processor och annat. Ett av de 8 registren reserverade man för systemets stackpekare resten kan programmeraren använda som han vill, för egna stackar och indexregister m m. Slutligen såg programmerarmodellen ut såhär: Vi ser att det bland annat finns en hel radda register som kallas dataregister, D0 D7. Med vår nomenklatur skulle vi kalla alla dessa för ackumulatorer. Adressregistren, A0 A7 är de som kan användas till stackpekare eller indexpekare eller bara mellanlagring av data om man så önskar. Mycket lite av registrens funktion är slagen i sten jämfört med en traditionell ackumulatormaskin, som modellprocessorn vi studerat hittills. 68000 är en typisk representant för vad som kallas en processor med generella register. Ingenjörerna på Motorola var framsynta vid konstruktionen av 68000. Den skulle ju vara flaggskeppet i deras produktlinje. Och den var faktiskt så bra att den levde kvar, frodades, växte och blev med tiden både 68010, 68020, 68030 och 68040. Där de senare var 32- bitars processorer. 68000-tankarna lever kvar än i dag i vad Motorola kallar CPU32, ett byggblock som är grundstenen i deras nya uppsättning processorer bl.a. Coldfire 2. Samtliga versioner har i huvudsak samma programmerarmodell och ett program skrivet för 68000 kan köras på en Coldfire om så skulle önskas. Omvändningen gäller dock inte ett program för 68010 kan använda nya instruktioner som den råa 68000 inte förstår. 4.2.1. Registeruppsättning För att summera egenskaperna hos registren i 68000 har vi alltså: 8 dataregister (ackumulatorer) 8 adressregister (som indexregister/pekarregister, SP!) 32 bitars registerlängd 4.2.2. Variabla operandstorlekar 32 bitar är ju coolt och bra och så, men många hävdar att man måste kunna hantera 8-bitars ord också. Bland annat eftersom man då kan packa en bokstav i varje ord. I det fallet vore det slöseri att använda ett fullt 32-bitars ord med bara en bytes nyttolast. Därför har man infört tre olika operandstorlekar: 2 Gå in på http://www.motorola.com och sök på coldfire 35

4. M68000 Byte Word Long Operandstorleken byte kan bara användas i dataregistren medan word och long kan användas överallt. 4.2.3. Minnesbredd Vi har förut nämnt att 68000 är en 16-bitars processor. Hur kan den vara det om den har 32-bitar breda register? Jo, den har 16-bitar utåt: Det är dessutom så att den har 24-bitars adressbuss utåt, så den kan adressera högst 2 24 = 16 megabyte minne. Minnet utförs vanligen med vanliga 8-bitar breda minneskretsar. Man tar två och lägger dem bredvid varann och låter processorns två signaler U DS och LDS peka ut rätt krets eller båda samtidigt om man vill komma åt ett 16-bitars ord. Detta är också anledningen till att ingen signal A0 finns ut från processorn. Den behövs helt enkelt inte! För den variant av 68000 som ingår i laborationerna, 68008, gäller att den har en 8-bitars databuss. Varje gång den ska hämta ett 16-bitars ord måste den alltså producera två 8-bitarsvärden på sin databuss. Resultatet blir detsamma när väl instruktionen är klar men det är ett långsamt sätt att hämta data. För att hämta ett ord i formatet long hämtar processorn automatiskt två på varann följande words. Att hämta ett long är alltså en långsam och omständlig procedur. Speciellt så på 68008 förstås. Exempel 36

4.2. Motorola 68000 en verklig processor Operander kan dessutom inte placeras var som helst utan måste placeras på jämn adress, så att UDS = LDS = 0 kan hämta en hel 16-bitars tugga. Även en long måste starta på jämn adress 3. En byte kan däremot hämtas både på jämn och udda adress. Det är programmeraren som är ansvarig för att placeringen av data blir rätt: MOVE.W 5,D0 är till exempel fel. Varför? 4.2.4. Automatisk teckenutvidgning (sign expansion) Adressregistren är speciella då de dels inte hanterar byteoperander och då de dels behandlas som om de innehöll tvåkomplementstal. Detta får till effekt att, om inte full (d.v.s. 32-bitars) adress används, betraktar processorn adressen som ett 16-bitars tvåkomplementstal och teckenutvidgar denna omedelbart till ett 32-bitars tal: Registervärde (adressregister, 32 bitar) 01010100 00000000 00001111 00010011 Efter teckenutvidgning 00000000 00000000 00001111 00010011 Syns utåt på kretsen 00000000 00001111 0001001- Registervärde (adressregister, 32 bitar) 01010100 00000000 10001111 00010011 Efter teckenutvidgning 11111111 11111111 10001111 00010011 Syns utåt från kretsen 11111111 10001111 0001001- Med assembler kan man på samma sätt bli förvånad om adressregistret använts med ordlängden.w: MOVE.L MOVE.W #0,A3 #$8000,A3 ger A3 med innehållet $FFFF8000 på grund av teckenutvidgningen i den andra raden. Av denna anledning är LEA (Load Effective Adress) en lämplig instruktion för att ladda adressregister. Den finns bara i varianten.l. Studera instruktionen i databladen 4. 3 Vad skulle hända om den tilläts börja på en udda adress? 4 Datablad återfinns i laborationshandledningen. 37

4. M68000 4.3. Instruktioner 68000 Med registermodellen framfo r oss kan vi bo rja programmera kretsen. Det som a r ofta a r intressantast na r man tittar pa en ny processor a r vilka instruktioner den kan hantera: Motorola sa ger att det finns 56 instruktioner. Tyva rr a terfinns bara 54 i tabellen... sa det beror va l pa hur man ra knar och om man vill skryta med ma nga instruktioner? Som tur a r beho ver vi inte anva nda alla instruktioner, men en del kommer vi inte ifra n. Vi ka nner igen kategorierna fra n tidigare. Egentligen a r det bara instruktionen MOVE som skiljer sig fra n vad ka nner till. MOVE ersa tter ba de LD och ST i modelldatorn, och det a r ju logiskt om man ta nker pa det. Trots sitt namn flyttar den dock inte na gonting, det handlar hela tiden om att kopiera data. Det finns ett antal instruktioner i kategorierna aritmetik, logik, hopp och branch. Inget nytt da r. Men det kan vara va rt att pa peka att ett absolut hopp anva nder JMP, medan ett hopp relativt nuvarande PC anva nder BRA. Det finns ocksa korta och la nga hopp men det beho ver vi inte bry oss om ha r. 4.3.1. Instruktionen i datablad Varje instruktion a r noggrannt beskriven i labkompendiet om Tutor. Det kra vs viss erfarenhet att la sa Motorolas egen dokumentation: (Ack, om jag bara hade den inskannad. Da skulle den vara ha r.) 38

4.3. Instruktioner 68000 4.3.2. Assembler, äntligen Som exempel tar vi instruktionen för binär addition: ADD. Det viktigaste efter en stunds programmerande är assemblersyntaxen: ADD ADD <ea>,dn Dn,<ea> Här betyder <ea> effektiv adress som vi känner den sedan förr. Man kan alltså t.ex. inte ADD A0,A5, det skulle krävt en syntax enligt ADD <ea>,<ea>. Vissa instruktioner har denna syntax, andra inte. Konsultera dokumentationen 5. 4.3.3. Adresseringsmoder Ett område där 68000 verkligen excellerar är adresseringsmoderna 6. 68000 är den sista verkliga processorn av CISC-typ (Complex Instruction Set Computer) och har, hart när, alla förekommande adresseringsmoder: Register MOVE.B D1,D0 5 I vårt fall t.ex. labkompendiet, där vi finner instruktionen ADDA, Add Address, som klarar av An både som källa och destination 6 Vid granskning av manuset påpekades att Motorolas 6809 inte är en dålig föregångare i detta avseende heller. Ut på nätet och kolla om det stämmer! 39

4. M68000 Omedelbar MOVE.W #$FACE,D3 Där det hexadecimala talet är ett tal och inte en adress. I det använda skrivsättet talar # om att det som följer är ett tal och $ att talet är skrivet i hexadecimal form. Exempel MOVE.B #10,D3 D3 := 0x0A MOVE.B #$10,D3 D3 := 0x10 MOVE.B $10,D3 D3 := M(16 10 ) Absolut MOVE.B $F0, D0 4.3.4. Exempelprogram I Dags för lite programmering som övning på adresseringsmoderna. 40

4.3. Instruktioner 68000 Exempel I minnescellerna $1100 och $1101 finns två +va 7 tal, placera det största talet i cellen $1102. Vi börjar med en registerplan, att rita upp verkligheten som vi ser den. Sedan är det bara att börja skriva assemblerkod: Vi kör en till: Exempel Beräkna och lagra resultatet i $1100. 255 1 Den här uppgiften är lite mer komplicerad. Registerplanen underlättar återigen. 7 +va läses positiva, och tvärtom för va. 41

4. M68000 Villkorsinstruktionen BNE testar Z-flaggan för att avgöra om föregående instruktion (SUB.W) räknat ner registret till noll eller inte. Prova hemma att räkna från 0 255 istället för att ladda räknaren med 255 från början. Fördel? Nackdel? 4.3.5. Ytterligare adresseringsmoder Indexerad (Motorola: Register Indirect) ADD.W (A3),D0 Indexerad med förskjutning ADD.W 2(A3),D0 42

4.3. Instruktioner 68000 Indexerad med postinkrement En ny mod, numer inte så ovanlig och mycket praktisk. CLR.W (A3)+...och samma med predekrement CLR.W -(A3) Vilken raderas nu? Lägg märke till (åtminstone i 68000) det bara finns predekrement och postinkrement inte preinkrement eller postdekrement. 4.3.6. Exempelprogram II Den sista adresseringsmoden är mycket praktisk och eliminerar behovet av separata nedräkningsinstruktioner. Exempel Nollställ minnet från $800 till och med $1234. 43

4. M68000 Nu äntligen den sista adresseringsmoden, som också är en typisk 68000-mod: Rätt komplex, men användbar om man vet hur! Register indirect with index and displacement MOVE.W $20(A3,D1.W),D0 4.4. Subrutiner i 68000 Subrutiner i 68000 är enkelt Man gör precis som vi vant oss vid så vi tar ett exempel omedelbart: Exempel Skriv en subrutin som beräknar udda paritet 8 av byten i D1. 8 Med udda paritet menas att summan av alla 1-or i talet skall vara udda. Om ett åttabitarstal förses med paritet är denna oftast den mest signifikanta biten (Pxxxxxxx). Motsvarande fast tvärtom då(!) kallas jämn paritet 44

4.4. Subrutiner i 68000 Subrutinen skall alltså räkna antalet 1-or i de 7 lägre bitarna. Och om antalet är jämnt sätta paritetsbiten, P, till 1 annars till 0. Talet ska inte förstöras, och rutinen får använda enbart D1. Lösningen till problemet hängde mycket på rotationsinstruktionen ROR...... skiftinstruktionen LSR... och den logiska instruktionen OR: 45

4. M68000 För subrutiner på 68000 har konstruktörerna valt följande konvention: Instruktion Innebörd JSR addr SP := SP 1, M(SP ) := P C + 1, P C := addr RTS P C := M(SP ), SP := SP + 1 Observera att SP = A7! Använd inte A7 till något annat. Som programmerare behöver jag inte öka stackpekaren eller så allt sånt sköts transparent och automatiskt av instruktionerna JSR och RTS. Då var det klart. Rutinen funkar! Nu återstår att skaffa riskkapital, starta firma, paketera och sälj rutinen för andra att använda i sina program? Tyvärr inte. Det återstår en teknikalitet: Rutinen använder inte bara D1 utan även D0 och D2! Det måste åtgärdas. Vi måste spara undan den anropande rutinens innehåll i D0 och D2 innan vi använder registren för att kunna återställa dom i oförvanskat skick då vi är klara. Vem ska spara undan registren? Det finns två alternativ: huvudprogrammet, eller subrutinen. Det är ju huvudprogrammets data så det ligger onekligen i dess intresse att spara dom. Vad händer om subrutinen modifieras så att även D3 påverkas? Det är synd att behöva ändra på alla ställen i huvudprogrammet anropet förekommer. Bättre är att ändra i subrutinen, det blir ju färre ändringar då. Eftersom subrutinen själv bäst vet exakt vad som ska sparas undan brukar man överlämna detta åt den senare. Man kan i princip välja vilket sätt som helst men det är i någon mening förstås renare att låta subrutinen ta hand om det. När vi bestämt att det är subrutinens uppgift att stuva undan de register som kommer att förstöras måste vi också klura ut ett sätt att göra det. Det anropande programmet hoppar till subrutinen med ett JSR, som vanligt, och ser till att D1 förses med rätt värde innan: 46

4.4. Subrutiner i 68000 Eftersom subrutinen använder egna register måste deras värde sparas undan innan de förstörs och återställas vid subrutinens slut. Var kan vara ett bättre ställe att lägga dom på än på returstacken? Stacken kan ofta, med fördel, användas för temporärlagring av data. Se bara till att poppa alla värden innan RTS. 4.4.1. Något att fundera över Stackhanteringen kan utnyttjas på flera olika sätt, för syften den kanske inte är avsedd för. Vad händer till exempel egentligen i dessa programsnuttar 9? MOVE.L MOVE.L MOVE.L MOVE.L D0,-(SP) D2,-(SP) (SP)+,D0 (SP)+,D2 Och vad kan det här vara? MOVE.L MOVE.L RTS #$8000, D0 D0,-(SP) Och detta: ADD.L #4, SP eller till och med det här: ADD.L #4, (SP) 9 Här står för tydlighets skull SP för stackpekarvärdet. Som vi nu vet skulle det i praktiken stå A7. 47

4. M68000 4.5. Avbrott, i allmänhet Vi lämnar nu 68000 för ett ögonblick och betraktar avbrott på modelldatorn. Vi har sett hur ett program kan få saker utförda i subrutiner som programmet anropar. Med instruktionen JSR kan vi i programmet anropa andra programsnuttar för att få beräkningar utförda och sedan hoppa tillbaka med RTS för att fortsätta som om inget hade hänt. Med avbrott kan en yttre enhet signalera till processorn att det är dags att hoppa till en särskild subrutin, en avbrottsrutin. Det låter kanske förvånande, men vi människor gör så hela tiden. Ett typexempel man brukar dra är telefonen: Vi går inte runt och provlyssnar i luren för att höra om någon råkar ringa just då. Vi är mer praktiska än så och har försett telefonen med en ringsignal så den själv kan kalla på uppmärksamhet när det behövs. Ett typiskt avbrott. När vi pratat klart kan vi fortsätta med vad vi nu höll på med. I stort sett på samma sätt går det till i en dator Vårt program gör viktiga beräkningar och vill inte bli stört. Speciellt finns det inte tid för programmet att gå runt och polla (dvs provlyssna i luren ) om en ny yttre enhet behöver uppmärksamhet. En yttre enhet kan behöva snabb service, till exempel om en tangent på tangentbordet blivit nedtryckt eller om sekundpulsen från den yttre klockan kommer. Dessa är en utmärkt situation för en avbrottsrutin. Tangentbordet lägger ut den nedtryckta tangentens binära värde på IN-enheten och påkallar sedan uppmärksamhet genom att dra i avbrottssignalen, dvs den säger här är den om du vill ha den. Processorn kollar just innan den påbörjar varje ny instruktion om någon ryckt i avbrottstsnöret. Om så är fallet väljer den bort nästa instruktion för ögonblicket och gör ett subrutinanrop den sparar återhoppsadressen på stacken i vanlig ordning till avbrottsrutinen istället. Avbrottsrutinen läser i sin tur in tecknet från tangentbordet, lagrar värdet i minnescellen för senaste tangent och hoppar sedan ur, tillbaka till huvudprogrammet, som inte märkt att något hänt 10 utan fortsätter med nästa instruktion. Det ser ut och fungerar som subrutinanrop med en viktig skillnad: Under pågående avbrottsrutin får inte ett nytt avbrott inträffa. Den s.k. avbrottsflaggan sätts för att hindra ytterligare avbrott. Då återhoppet sker måste denna nollställas igen och av denna anledning används en speciell återhoppsinstruktion, RTI (ReTurn from Interrupt) 11. 10 Om det inte haft ett stoppur och kunnat mäta tiden. För det tar naturligtvis lite tid att utföra avbrottsrutinen. 11 Man kan också tänka sig att ytterligare processorinnehållmed automatik lagras på stack vid avbrott. Speciellt statusregistret är vanligt att man sparar på detta sätt. Men inte alla processorer gör det. 48