CE_O3. Nios II. Stackhantering och förberedelse för lab nios2time

Relevanta dokument
CE_O3. Nios II. Inför lab nios2time

CE_O2. Nios II. Subrutiner med mera.

CE_O1. Nios II. Enkla assembler-instruktioner.

Lösningar till tentamen i EIT070 Datorteknik

Lösningar till övning CE_O CE_O6. Parallell in/utmatning (I/O). Förberedelser till laboration nios2io.

Mål. Datorteknik. Innehåll. Innehåll (forts) Hur ser ett program ut? Hur skapas maskinkoden?

Stack och subrutiner Programmeringskonventionen

Datorsystem Laboration 2: Minnesmappade bussar

Övning 6. Parallellport, timer

IS1200 Datorteknik. Övning CE_O4 Maskinnära programmering med C Förberedelser till hemlaboration 1

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

Institutionen för elektro- och informationsteknologi, LTH

Datorteknik. Föreläsning 3. Assembler, stack och subrutiner, programmeringskonventionen. Institutionen för elektro- och informationsteknologi, LTH

Digital- och datorteknik

A-del motsvarande KS1

Kontrollskrivning Mikrodatorteknik CDT S2-704

Institutionen för elektro- och informationsteknologi, LTH

Datorteknik. Föreläsning 2. Programmering i C och assembler MIPS instruktionsarkitektur. Institutionen för elektro- och informationsteknologi, LTH

I denna laboration undersöker vi hur aritmetiska beräkningar utförs. Vi tittar på olika variabeltyper: 8-bitars, 16-bitars, 32-bitars och flyttal.

Lösningar till tentamen i EIT070 Datorteknik

Laboration 2 i Datorteknik- Assemblerprogrammering II

Mål. Datorteknik. Innehåll. Vad händer med en add-instruktion? Vad händer med en add-instruktion. Instruktioner som bitmönster i minnet

Besvara de elektroniska frågorna (se kurshemsidan). Läs kapitel i kursbok.

Tentamen i IS1500/IS1200/2G1518 Datorteknik fredagen den 19 augusti 2011 kl

Övningsuppgifter STYRNING - i Mikrodatorteknik för U2 2010

Föreläsning 2. Operativsystem och programmering

Programmering i maskinspråk (Maskinassemblering)

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

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

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

Övning2 Datorteknik, HH vt12 - Programmering

F5: Högnivåprogrammering

F5: Högnivåprogrammering

Tentamen. Datorteknik Y, TSEA28

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

Exempeltentamen Datorteknik, EIT070,

TSEA28 Datorteknik Y (och U)

Extra lab. Nu på fredag kl 8-12 Frivillig Enbart hjälp med projektuppgiften Ingen examination

PC-teknik, 5 p LABORATION ASSEMBLERINTRODUKTION

Lågnivåprogrammering. Föreläsning 2 Lågnivåprogrammering. Binära tal. En enkel modell av datorns inre

LEU240 Mikrodatorsystem

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

Inledning. Vad är ett datorprogram, egentligen? Olika språk. Problemlösning och algoritmer. 1DV433 Strukturerad programmering med C Mats Loock

Tentamen den 14 januari 2015 Datorarkitekturer med operativsystem, EDT621, 7,5 poäng

Institutionen för datavetenskap 2014/15

Programmering i maskinspråk (Maskinassemblering)

TSEA28 Datorteknik Y (och U)

4. Maskinnära programmering i C. Förberedelser till hemlaboration 1.

IS1500 Lösningar övning CE_O CE_O7. Programmerad in/utmatning. Serieport. Förberedelser till nios2io.

Digital- och datorteknik

Digital- och datorteknik

Svar till tentamen den 16 december 2013 Datorarkitekturer med operativsystem, EDT621, 7,5 poäng

Ansvarig lärare: Olof Andersson, Telefon (besöker skrivsalen)

Datorarkitekturer med operativsystem ERIK LARSSON

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.

CPU. Carry/Borrow IX. Programräknare

TENTAMEN. Datorteknik. D1/E1/Mek1/Ö Hjälpmedel: Häfte "ARM-instruktioner", A4-format, 17 sidor. Maxpoäng:

Datorsystemteknik DVGA03 Föreläsning 8

Lösningsförslag till tentamen i IS1500 Datorteknik

Assemblerprogrammering för ARM del 2

Digital- och datorteknik

Grundläggande datavetenskap, 4p

Datorsystemteknik DVG A03 Föreläsning 3

LABORATION DATORTEKNIK D. Pipelining. Namn och personnummer. Version: (OS,OVA,AN)

Till assemblersystemet Zuper 80 Assembler krävs en SPECTRAVIDEO 328/318+minst 16K ram extra.

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

Introduktion till programmering och Python Grundkurs i programmering med Python

LABORATION. Datorteknik Y

Tentamen. Datorteknik Y, TSEA28

TSEA28 Datorteknik Y (och U)

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

Laboration Datorteknik TSIU02 2. I/O-programmering

TSEA28 Datorteknik Y (och U)

Digital- och datorteknik

Digitalteknik EIT020. Lecture 15: Design av digitala kretsar

Programmering av inbyggda system. Kodningskonventioner. Viktor Kämpe

Tentamen. Datorteknik Y, TSEA28

Tentamen. Datorteknik Y, TSEA28

Datorarkitekturer med operativsystem ERIK LARSSON

Föreläsning 1: Intro till kursen och programmering

Tentamen. Datorteknik Y, TSEA28

Programexempel för FLEX

Laboration nr2 med enchipsdatorn PIC-16F877

Datorteknik 2 (AVR 2)

Datorsystemteknik DAVA14 Föreläsning 10

Lista på registeruppsättningen i PIC16F877A Datablad TTL-kretsar 74-serien

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

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

Tentamen (Exempel) Datorteknik Y, TSEA28

Lösningar till tentamen i EIT070 Datorteknik

Datorteknik ERIK LARSSON

Tentamen den 18 mars svar Datorteknik, EIT070

CE_O6. Parallell in/utmatning (I/O). Förberedelser till laboration nios2io.

Digitala System: Datorteknik ERIK LARSSON

Läs igenom hela laboration 5 innan du börjar beskriva instruktionsavkodaren i VHDL!

Assemblerprogrammering del 3

Programmering i C++ En manual för kursen Datavetenskaplig introduktionskurs 5p

Styrteknik: MELSEC FX och numeriska värden

Tentamen. Datorteknik Y, TSEA28

Transkript:

IS1200 ösningsförslag till övning CE_O3 2015 CE_O3. Nios II. Stackhantering och förberedelse för lab nios2time 3.1. ogiska operationer Nios II kan utföra de logiska operationerna AND, OR, XOR och NOR. Var och en av operationerna utförs bitvis, det vill säga varje bitposition i källoperanderna behandlas separat för att beräkna motsvarande bitposition i resultatet. Exempel med bitvis AND (logiskt OCH): bitvis operation varje bit behandlas separat 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 1 0 1 0 0 0 1 1 1 & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 1 0 1 0 0 0 1 0 1 Bland annat i programmeringsspråket C skrivs bitvis OCH med tecknet &. Bitvis OR fungerar på liknande sätt men gör förstås en logisk EER-operation i varje bitposition: om någon av de två källoperandbitarna är ettställd, så blir motsvarande resultatbit ettställd. Bland annat i programmeringsspråket C skrivs bitvis EER med tecknet. Operationen bitvis XOR (exklusivt EER) ger en etta i resultatbiten om de två källoperandbitarna är olika: 0 xor 0 == 0; 0 xor 1 == 1; 1 xor 0 == 1; 1 xor 1 == 0. Det sista fallet skiljer sig alltså från "vanligt" OR. "Vanligt" OR kallas ibland inklusivt EER (inclusive OR), när man behöver tydligt markera att man inte menar XOR. Operationen NOR har följande sanningstabell (se nästa sida)... Resultatet kan ses som en invertering av EER (inverted OR). ösningsförslag till övning CE_O3, sida 1 (av 12) 2015-01-13

Instruktionerna för AND, OR och XOR finns i både R-format, med två källoperander i register, och i I-format med ena källoperanden i instruktionen (immediate). För I-formatet används ingen sign-extension. I stället fylls immediate-värdet alltid ut med nollställda bitar. För ANDI, ORI och XORI fyller processorn ut med nollor till vänster om de immediate-bitar som angetts i instruktionen. Det finns dessutom instruktionerna ANDHI, ORHI och XORHI; för dessa fyller processorn ut med nollor till höger om immediate-bitarna i instruktionen. Instruktionen NOR finns bara i R-formatet. Dess viktigaste användning är för invertering av alla bitar i ett register. Detta kan utföras antingen med eller operation NOR NOR resultat 0 nor 0 1 0 nor 1 0 1 nor 0 0 1 nor 1 0 R9,R8,R8 R9,R8,R0 I båda dessa exempel läses värdet i register R8, alla bitarna i värdet inverteras, och resultatet skrivs till R9. a) Operandutpekningsmetoderna är följande. Resultatet placeras alltid i ett register. Den ena källoperanden finns alltid i ett register. För AND, OR och XOR kan källoperanden finnas antingen i ett register, eller som konstanta immediate-bitar i själva instruktionen. Det får ju bara plats 16 bitar med immediate-värde i instruktionen, och för dessa instruktioner fylls värdet alltid ut med nollor så att processorn kan arbeta med en 32-bits operand. NOR finns bara med båda källoperanderna i register. b) En viss bitposition kan alltid bara påverka sin egen motsvarande bitposition i resultatet. Det kan ses som att dessa instruktioner alltid opererar på bitvektorer med den fasta längden 32 bitar. ösningsförslag till övning CE_O3, sida 2 (av 12) 2015-01-13

c) För att nollställa en enda bit i ett register, till exempel bit nummer 4 (med nollnumrering), krävs en del eftertanke. Det är lätt att ens assemblerprogram nollställer flera bitar än man tänkt sig. För att få det rätt börjar vi med att konstruera en konstant med bara bit 4 ettställd: MOVI R11,0x10 # Binärt 00...0010000 Därefter inverterar vi denna konstant. Då får vi ett 32-bits värde med alla bitar ettställda utom just bit 4: NOR R11,R11,R0 # Invertera innehållet i register R9 Nu kan vi nollställa bit nummer 4 i ett annat register, till exempel register R8: AND R8,R8,R11 # Nollställ bit 4 i R8 d) Ettställa en bit i ett register är enkelt med instruktionen ORI (eller ORHI, om den bit som ska nollställas är bit 16 eller högre): ORI R9,R9,0x04 # Ettställ bit 2 i R9 e) För att invertera en enda bit i ett register används med fördel XORI (eller XORHI, om den bit som ska inverteras är bit 16 eller högre): XORI R10,R10,0x80 # Invertera bit 7 i register R10 f) Oj, detta har vi redan gjort i en tidigare deluppgift:* NOR R11,R11,R0 # Invertera alla bitar i register R11 3.2. adda en konstant till ett register a) Konstanten ryms i 16 bitar. Man kan därmed använda instruktionen movi rb,immed Det fungerar bra med 16-bitars negativa värden, eftersom sign-extension görs innan konstanten IMMED kopieras till destinationsregistret. Därför kan man ange positiva och negativa värden som ryms i 16 bitars 2-komplementsrepresentation, det vill säga värden från och med -2 15 till och med 2 15-1, alltså -32768 till +32767. Ett specialfall som fungerar mycket bra är instruktionen movi r2, 1 Naturligtvis kan r2 bytas mot valfritt annat register. Instruktionen movi är en pseudoinstruktion som implementeras som addi rb,r0,immed b) Konstanten ryms inte i 16 bitar, men däremot i 32 bitar. Då används pseudoinstruktionen movia rb,immed som översätts till två maskininstruktioner. Dessa två maskininstruktioner medför tillsammans att 32 bitsvärdet IMMED skrivs till register rb. Negativa värden fungerar tyvärr inte på grund av ett fel i översättaren. Detta gäller även det ganska vanliga värdet -1. Varning! c) Nollställning av register r17 kan till exempel göras såhär: movi r17,0 Detta är enkelt och lättläst. Pseudoinstruktionen movi översätts till addi r17,r0,0 och den instruktionen har binärkoden 00000 10001 0000 0000 0000 0000 000100 ösningsförslag till övning CE_O3, sida 3 (av 12) 2015-01-13

d) Att ladda +1 i register r17 kan till exempel göras såhär: movi r17,1 Pseudoinstruktionen movi översätts till addi r17,r0,1 och den instruktionen har binärkoden 00000 10001 0000 0000 0000 0001 000100 Att ladda -1 i register r17 kan till exempel göras såhär: movi r17, 1 Pseudoinstruktionen movi översätts till addi r17,r0, 1 och den instruktionen har binärkoden 00000 10001 1111 1111 1111 1111 000100 Talet -1 kodas i 2-komplementsrepresentation som ett ord med alla bitar ettställda. 3.3. Pseudo-instruktioner och makron a) Makro för INV reg som inverterar alla bitar i registret reg:.macro INV reg NOR \reg,\reg,\reg.endm b) Makro för NEG reg som negerar talet i registret reg, det vill säga vänder talet från positivt till negativt eller tvärtom:.macro NEG reg SUB \reg,r0,\reg.endm c) Makro för ADDIA ra,rb,value.macro ADDIA ra,rb,value movia r1,\value add \ra,\rb,r1.endm ösningsförslag till övning CE_O3, sida 4 (av 12) 2015-01-13

3.4. Subrutin för multiplikation av två godtyckliga tal, med hjälp av additioner och skift a) Flödesschema: start a = factor1 b = factor2 product = 0 i = 32 lsb of a == 1? NO YES product = product + b shift a right shift b left i = i - 1 return value = product YES i > 0? NO return ösningsförslag till övning CE_O3, sida 5 (av 12) 2015-01-13

Subrutinen kan skrivas såhär: mul: mov r8,r4 # kopiera ena talet, a mov r9,r5 # kopiera andra talet, b movi r2,0 # totalsumma movi r11,32 # slingvariabel 1: andi r12,r8,1 # a & 1 testa en bit beq r12,r0,2 # hoppa förbi addition om biten = 0 add r2,r2,r9 # total = total + b 2: srli r8,r8,1 # a >> 1 slli r9,r9,1 # b << 1 subi r11,r11,1 # i = i 1 bgt r11,r0,1 # loop klart: ret Denna subrutin ska ta (cirka) 4 + 4 + 32 ( 1+2+1+3+3+1+2) = 456 klockcykler på den Nios II/s som används på laborationerna. Instruktioner slli/srli tar 3 klockcykler med den hårdvara som finns på laborationerna, mov/movi/add tar 1 cykel och ret tar 4 cykler. För beq och bgt har här räknats med 2 cykler. En viktig observation är att tiden för en multiplikation är ganska konstant och oberoende av storlek på de tal som multipliceras, men ganska lång tyvärr. Noggrannare: För att komma fram till detta värde gjordes följande beräkningar. Instruktionerna i slingan är andi beq add srli slli subi bgt. Instruktionen beq hoppar framåt, och hoppet tas normalt inte; detta fall ger en körtid på 1 klockcykel. Instruktionerna add och subi tar 1 klockcykel vardera. Instruktionen bgt hoppar bakåt och tas i 30 fall av 31; detta fall ger en körtid på 2 klockcykler. Summan är alltså 5 klockcykler per varv. Vanligtvis kan man acceptera att tiden varierar beroende på indata. I så fall kan man avbryta loopen så snart tal a (i r8) har blivit noll. Eftersom srli skiftar in nollor i a, så kan man bevisa att a kommer att få värdet noll senast efter 32 steg (för 32 bitar). Det gör att man kan utesluta slingvariabeln (loopräknaren) och förenkla subrutinen. ösningsförslag till övning CE_O3, sida 6 (av 12) 2015-01-13

Förenklad version: start a = factor1 b = factor2 product = 0 lsb of a == 1? NO YES product = product + b shift a right shift b left return value = product NO a == 0? YES return ösningsförslag till övning CE_O3, sida 7 (av 12) 2015-01-13

3.5. Programutveckling Diskutera de olika steg som ingår i arbetet med att skriva och provköra ett program i c-kod och assemblerkod. Vilken typ av kommandon kan vara praktiskt att ha tillgång till och vilka filer vill man ha genererade? Om detta finns en hel del föreläsningsbilder från föreläsning 3 och/eller 4. Kortfattat Editering: Skriv din c-kod i en textfil med en editor Kompilering: åt en kompilator översätta din textfil med c-kod till textfil med assemblerkod för den processor som ska exekvera programmet. Det är rimligt att förvänta sig att det går att studera den assemblerkod som genereras vid kompilering. En kompilator kan utföra olika grader av optimering. Det kan vara lärorikt att jämföra c-kod med den assemblerkod som kompilatorn genererar. (det kan vara en utmaning att försöka skriva bättre assemblerkod än den som kompilatorn levererar) Editering: Skriv din assemblerkod i en textfil med en editor eller redigera assemblerkoden som kompilatorn genererar. Assemblering: åt en assembler översätta från textfilen med assemblerkod till en objekt-modul som innehåller koden i maskinkod dvs de värden (binära/hexadecimala) som finns i minnet vid exekvering. Objektmodulen innehåller även information om symbliska adresser som ännu inte är kopplade till fysiska adresser. änkning: Objektmodulen länkas ihop med eventuella andra objektmoduler och eventuella biblioteksmoduler. Alla symboliska adresser kopplas ihop med fysiska adresser och det skapas en ladd-modul som innehåller all information som behövs för att kunna ladda programmet till minnet och starta exekvering. addmodulen kan eventuellt vara relokbar dvs vara utformad så att programmet kan placeras på valfri ledig plats i det fysiska minnet. addning: Informationen i laddmodulen skrivs till processorn minne. Exekvering: Starta exekvering av det laddade programmet Avlusning: Provkör och verifiera att programmet till alla delar fungerar enligt specifikationerna. Korrigera vid behov upptäckta fel. Extra-filer: förutom laddmodulen skapas andra filer som är användbara vid felsökning, verifiering och dokumentation av programmet. Vid programutveckling behövs speciella kommandon för varje steg. Alternativt arbetar man i en interaktiv programutvecklingsmiljö som ger stöd för filhantering och alla steg enligt ovan som ingår i att ta fram ett fungerande program. ösningsförslag till övning CE_O3, sida 8 (av 12) 2015-01-13

3.6. Minnesdisposition Se figur till höger. adress 0 ROM Observera att det finns programkod som körs före ditt program. Den programkoden tilldelar bland annat ett lämpligt startvärde till stackpekaren. 3.7. Mall för ett program I början av programmet placeras include av filer med makro-definitioner. Därefter placeras egendefinierade symboler (namn) och egendefinierade extra makron. adress 0x800 in-/ut-portar adress 0xa20 adress 0x800000 adress 0x1000000 adress 0xffffffff tomt och oanvändbart minne ännu mera tomt och oanvändbart Därefter placeras globala variabler och globala subrutiner/funktioner. Sist kommer huvudprogrammet, main-programmet, som förstås kan använda globala variabler och funktioner samt definerade symboler och makron. 3.8. Vilka program ska skrivas i laboration nios2time ÖSNINGSFÖRSAG SAKNAS. 3.9. Biblioteksrutinen putchar.text.align 2 movi r4,'\n' # lägg styrtecknet Newline i r4 för att få ny rad call putchar # anropa putchar för utskrift movi r4,'h' # lägg tecknet H i r4 call putchar # anropa putchar för utskrift movi r4,'e' # och så vidare call putchar movi r4,'j' call putchar movi r4,'!' call putchar ösningsförslag till övning CE_O3, sida 9 (av 12) 2015-01-13

3.10. Hallå där vänta en liten stund a) Flödesschema, se figur längst ner på sidan. b) Programkod:.data.equ param,1000 # med param menas 1000 (första gissning).text.align 2.global wait wait: movia r8,param # param är startvärde test: ble r8,r0,out # testa om vi räknat hela vägen ner till 0 subi r8,r8,1 # räkna ner ett steg till br test # gör om out: ret Nu följer ett kortfattat resonemang för att få fram ett bättre värde på param. Processorns klockfrekvens är 50 MHz. Anta att varje instruktion tar en klockcykel. Varje varv i vår loop körs 3 instruktioner. Hur många varv behövs för att det ska ta 1 millisekund? 1 millisekunder motsvarar 0,001 * 50 miljoner klockcykler, det vill säga 50 000 klockcykler. Om vi dividerar detta tal med 3 får vi fram hur många varv loopen ska köras. Det blir 16 667 varv, så param ska vara 16 667 i stället för 1000. När man provar detta i praktiken visar det sig att tiden blir för lång. Vissa instruktioner tar mer än en klockcykel. ösningsförslag till övning CE_O3, sida 10 (av 12) 2015-01-13

3.11. Hallå där vänta en lite längre stund a) Flödesschema, se figur. b) ägg märke till att returadressen i r31 måste skyddas om man gör subrutinanrop i en subrutin. Vi förutsätter att makrona PUSH och POP är definierade..text.align 2.global waitx waitx: PUSH r31 # skydda innehållet i r31 outer: ble r4,r0,klar # hoppa ut direkt om parametern 0 inner: PUSH r4 # wait får ändra r4, så skydda r4 call wait # vänta 100 millisekunder POP r4 # återställ r4 subi r4,r4,1 # minska parametern ett steg br outer # kör kanske ett varv till klar: POP r31 # återställ returadressen till r31 ret # returhopp från subrutin Varje varv i loopen i waitx görs ett anrop till wait, som tar 100 millisekunder. Det tillkommer tid för ett antal instruktioner förutom anropet till wait. Det är i stort sett omöjligt att få en fördröjning som är exakt r4 gånger 100 millisekunder. Anrop med värdet 0 i r4 ger inte fördröjning 0 utan minst 5 klockcykler, vilket kanske är försumbart men ändå mer än 0. ösningsförslag till övning CE_O3, sida 11 (av 12) 2015-01-13

3.12. Assemblerdirektiv Diskutera olika assemblerdirektiv som finns (och borde finnas eller tvärtom!)!. Information om assemblerdirektiv finns i kursboken (4.6) samt i avsnitt 7 i skriften Introduction to the Altera Nios II Soft Processor som finns på kurswebben. Här följer några enkla användbara exempel Reservera minnesplats.byte 0x45, 0x3E, 0xa, 0xd # fyra 8-bits bytes med innehåll.halfword 0xabcd, 0x1234 # två 16-bits ord med innehåll.word 0x1ab23 # ett 32-bitars ord med innehåll.word 0 # ett 32-bits ord med innehåll 0 STAR:.byte '*' # en byte med asciikod för * KOON:.byte ':' # en byte med asciikod för :.fill 32, 4, 0xDEADCODE # 32 st 4-bytes-ord med innehåll Man bör skilja mellan data och program för att hjälpa kompilatorn. Vissa processorer skiljer hårdvaran mellan kod och data och programmet avbryts om progammet försöker utföra (OAD och) STORE på minnesadresser som hör till kodarean.data.text # det som nu kommer ska placeras i data-area # det som nu kommer ska placeras i program-arean Det bör finnas direktiv för att ange att en symbolisk beteckning ska vara global och tas med i den globala symboltabellen. Detta kommando har släktskap med public som används i java..global main, hexasc.end # anger att översättaren kan sluta översätta # och det som kommer efter.end kan ignoreras Det är praktiskt att kunna införa egna symboliska beteckningar på konstanter.equ elephant, 4711 ösningsförslag till övning CE_O3, sida 12 (av 12) 2015-01-13