Bra sätt att välja en viss subrutin i assembler, PIC18F442

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
nanopile
Inlägg: 312
Blev medlem: 9 april 2006, 17:06:50
Ort: Stockholm

Bra sätt att välja en viss subrutin i assembler, PIC18F442

Inlägg av nanopile »

Hur gör ni när ni har ett antal subrutiner att välja emellan?
Tex såhär har jag gjort.

Kod: Markera allt

movlw 0x3E
cpfseq NåttVärde
goto SkipAhead1
Call RättRutin_A

SkipAhead1
movlw 0xBE
cpfseq NåttVärde
goto SkipAhead2
Call RättRutin_B

SkipAhead2
movlw 0x0A
cpfseq NåttVärde
goto SkipAhead3
Call RättRutin_C
SkipAhead3
Helst skulle jag vila ha cpfseq att hoppa över när den inte är lika med WREG.
Men finns det ett bättre sätt?
Datablad: http://ww1.microchip.com/downloads/en/D ... 39564c.pdf
Senast redigerad av nanopile 25 september 2008, 22:41:28, redigerad totalt 5 gånger.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Använd code-taggarna så att sk--en går att läsa !!!
nanopile
Inlägg: 312
Blev medlem: 9 april 2006, 17:06:50
Ort: Stockholm

Inlägg av nanopile »

Ändrade, hoppas det blev som du önskade :)
Annars kan jag iofs göra om igen bara jag lyckas lista ut hur.
Användarvisningsbild
Marta
EF Sponsor
Inlägg: 7487
Blev medlem: 30 mars 2005, 01:19:59
Ort: Landskrona
Kontakt:

Inlägg av Marta »

Du beskriver lite luddigt vad Du vill åstadkomma.

Om alla värdena för att välja rutin med ligger i följd så gör en lista med en GOTO till varje rutin. Gör sedan en CALL till en rutin som tar NåttVärde och lägger till en offset för denna lista samt stoppar in resultatet i PC? och saken är klar.

Ligger värdena inte i sekvns så gör en lista med omväxlande RETLW samt GOTO till tillhörade rutin. Hämta och komparera värdet, stämmer det inte såinkrementera två gånger och fortsätt loopen. Stämmer det så inkrementera en gång och hoppa till adressen.

Lite rörigt beskrivet, men är inte alls något svårt. SÖK PÅ "jump table" så hittar Du nog en bättre beskrivning.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Den där koden kan inte gå igenom MPASM utan felmeddelanden
om att det finns kommandon i position 1. Det får inte finnas annat
än labels i position 1. Det bör se ut ungefärså här:

Kod: Markera allt

    movlw    0x3E
    cpfseq   NåttVärde
    goto     SkipAhead1
    Call     RättRutin_A

SkipAhead1
    movlw    0xBE
    cpfseq   NåttVärde
    goto     SkipAhead2
    Call     RättRutin_B

SkipAhead2
    movlw    0x0A
    cpfseq   NåttVärde
    goto     SkipAhead3
    Call     RättRutin_C

SkipAhead3
Du vill alltså anropa tre olika rutiner beroende på om det är h'3E', h'BE', eller h'0A' ?
Jo, det verkar den väl göra.
Jag skulle lägga in en extra GOTO efter varje CALL, det är ju onödigt att
köra resten av testera.

Om du har 100-tals olika värden så finns det bättre metoder (som Marta
nämnde).

Jag antar att de två vrderna bara var exempel, annars (med just *de* tre
värderna) går det att göra enklare...
Nerre
Inlägg: 27257
Blev medlem: 19 maj 2008, 07:51:04
Ort: Upplands väsby

Inlägg av Nerre »

Som jag fattar det så är han ute efter att skippa de extra goto som blir.

Så som han har nu blir det ju

(Jag kan inte PIC assembler så det blir pseudokod)

Kod: Markera allt

read
if > then skip
skip
call
read
if > then skip
skip
call
men han vill ha

Kod: Markera allt

read
if < then skip
call
read
if < then skip
Men som sagt var, han får ju traggla igenom alla extra jämförelser efter return också... Jag skulle nog gjord EN subrutin och sen lagt den där koden i början av den och hoppat till de olika avsnitten (som interruptvektorerna i AVR t.ex. fungerar).

Kod: Markera allt

.
.
    call foo
.
.
.


foo  read
       if > goto A
       if > goto B
.
.
.

A   massa kod
.
.
return

B   massa kod
.
.
return
Ok, ska man göra "rätt" ska man bara ha en return och hoppa ut till den, men just i ett sånt här läge tycker jag det är motiverat med flera return.
Skriv svar