Maskinnära programmering i C och assembler
Maskinnära programmering i C och assembler
Maskinnära programmering i C och assembler
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
Stand Alone Applikation<br />
I detta moment visar vi hur du enkelt skapar en<br />
fristående applikation (dvs utan användning av<br />
färdiga programbibliotek). Vi delar upp<br />
applikationen i två olika källtexter:<br />
appstart.s12<br />
ml4.c<br />
appstart.s12 innehåller, som namnet antyder,<br />
den nödvändiga koden för att starta C-programmet,<br />
vars huvudfunktion (”huvudprogram”) alltid heter<br />
”main”. En minimal ”appstart” blir följaktligen:<br />
* Här börjar exekveringen...<br />
JSR _main<br />
*<br />
Observera “underscore” framför symbolnamnet.<br />
Detta är en konvention hos XCC <strong>och</strong> används för<br />
att ingen sammanblandning ska kunna ske mellan<br />
applikationsdefinierade symboler <strong>och</strong> reserverade<br />
namn. Då vi vill referera symboler som definierats i<br />
någon C-källtext ( i detta fall ”main”) måste vi<br />
alltid tänka på denna konvention.<br />
Vår minimala "appstart" kan vara riskabel, vad<br />
händer om inte stackpekaren har ett riktigt värde<br />
vid anropet ? I värsta fall spårar programmet ur<br />
redan då eftersom instruktionen (JSR) innebär att<br />
återhoppsadressen läggs på stacken. Vi garderar oss<br />
genom att lägga till en instruktion som initierar<br />
stackpekaren:<br />
* Här börjar exekveringen...<br />
LDS #$2FFF<br />
JSR _main<br />
*<br />
Vad händer nu å andra sidan om exekveringen<br />
avslutas i ”main” <strong>och</strong> processorn försöker återuppta<br />
den efter JSR-instruktionen ??? Förmodligen löper<br />
programmet amok på ett mer eller mindre<br />
okontrollerat sätt. Vi kan gardera oss även mot<br />
detta.<br />
* Här börjar exekveringen...<br />
LDS #$2FFF<br />
JSR _main<br />
exit: NOP<br />
BRA exit<br />
*<br />
Dvs vi avslutar med en oändlig programslinga där<br />
programmet inte gör någonting.<br />
I en del applikationer vill man kunna avsluta med<br />
ett direkt anrop av funktionen ”exit” från ett<br />
program. Vi kan enkelt möjliggöra detta nu men<br />
måste då komma i håg kompilatorns<br />
namnkonventioner. För att kunna referera en<br />
symbol som definierats i en <strong>assembler</strong>källtext måste<br />
symbolen inledas med ’_’. Vår version av<br />
”appstart” blir då:<br />
* Här börjar exekveringen...<br />
LDS #$2FFF<br />
JSR _main<br />
_exit: NOP<br />
BRA _exit<br />
Arbetsbok för MC12<br />
*<br />
För att avsluta ett C-program krävs nu bara<br />
funktionsanropet:<br />
exit();<br />
Det är nu bara några små detaljer kvar för att vår<br />
”appstart” ska kunna användas.<br />
Symbolen ”_main” är definierad i en annan<br />
källtext. Vi talar om detta för assemblatorn med<br />
direktivet:<br />
extern _main<br />
På motsvarande sätt gäller att symbolen ”_exit”<br />
definierats i appstart.s12. Vi talar om för<br />
assemblatorn att denna symbol ska vara global, dvs<br />
kunna refereras från en annan källtext, med<br />
direktivet:<br />
define _exit<br />
Vi måste också definiera ett segment för koden.<br />
Eftersom detta är så kallad ”startup-kod” använder<br />
vi segmentet startupseg. Segmentnamnet<br />
'startupseg' använder vi för att skapa ett ”inträde” i<br />
programmet. Vid länkningen ger vi segmentet en<br />
lämplig startadress. På detta sätt är det lätt att<br />
bestämma en väldefinierad startpunkt för vår<br />
applikation. Segmentet får bara definieras i en fil i<br />
applikationen. Vår slutliga ”appstart” blir:<br />
segment startupseg<br />
define _exit<br />
extern _main<br />
* Här börjar exekveringen...<br />
LDS #$2FFF<br />
JSR _main<br />
_exit: NOP<br />
BRA _exit<br />
*<br />
UPPGIFT 119:<br />
Skapa en källtext APPSTART.S12 enligt<br />
ovanstående anvisningar. Du kommer att få<br />
användning av den om en stund.<br />
SLUT PÅ UPPGIFT 119.<br />
Vi övergår nu till själva applikationen, dvs ”main”.<br />
Vi ska skriva ett enkelt program som läser från en<br />
inport, skiftar detta värde ett steg till höger <strong>och</strong><br />
skriver resultatet till en utport (Jämför inledande<br />
exempel i Avsnitt 1).<br />
Denna uppgift visar exempel på hur fysiska portar,<br />
eller absoluta adresser i allmänhet, kan kommas åt<br />
direkt från ett C-program. Man behöver alltså inte<br />
(vilket är en vanlig missuppfattning) använda<br />
<strong>assembler</strong>rutiner bara därför att man exempelvis<br />
skriver rutiner som hanterar speciella<br />
periferienheter.<br />
89