Sida 2 av 3
Postat: 2 december 2008, 01:16:32
av sodjan
AndersG har helt rätt. värdet av "$" (d.v.s aktuell adress) måste vara känt
av MPASM (eftersom det är MPASM som gör alla "assembly-time calculations"),
men i reloc-mode så är det först MPLINK som vet (och bestämmer) var koden
ska hamna. Funegrar inte alltså.
(Och det har ingenting med att det ligger i ett MACRO att göra...)
Och skulle det ha gått att göra så där, så hade det sannolikt redan
varit känt och dokumenterat...

Postat: 2 december 2008, 06:36:19
av persika
Då är det en nackdel i relokerbar mod.
Så man får välja..
om man själv sätter adresserna till de olika segmenten och kan använda det automtiska makrot för anrop av subrutiner, i absolut mod då,
eller...
får adresserna till segmenten automatiskt och själv få hålla reda på hur subrutiner ska anropas, i reloc mod.
Postat: 2 december 2008, 08:22:46
av AndersG
Normalt uppväger fördelarna med relokerbar nackdelarna, speciellt i större projekt. Jag ser inget problem att alltid använda
Kod: Markera allt
;**********************************************************************************************************
; the fcall macro - do a far call and set PCLATH correctly upon return
; by Roger Froud of Amytech Ltd.
fcall macro subroutine_name
local here
lcall subroutine_name
pagesel here
here:
endm
Man förlorar så litet och om man är desperat efter dendär sista nanosekunden i en ISR kan man ju handoptimera. Värre är det då med konstruktioner av typen:
Kod: Markera allt
movlw high displaymode0
movwf pclath
banksel dspmode
movf dspmode,w ; Get display mode in W
andlw .7 ; Make sure it is within bounds (0..7)
addwf pcl,f ; Add it as offset to program counter
goto displaymode0 ; Jump table to display mode handlers
goto displaymode1
goto displaymode2
goto displaymode3
goto displaymode4
goto displaymode5
goto displaymode6
goto displaymode7
Postat: 2 december 2008, 09:38:39
av vfr
Skall man göra på det sättet, så får man göra en grov indelning i olika block och placera programmodulerna där man tror att dom passar bra minnesmässigt. Sedan får man kanske göra justeringar efterhand som kodblocken ändrar storlek. Men då är det grovjusteringar. Finliret tar ändå länkaren hand om.
Postat: 5 december 2008, 22:26:18
av persika
Har gjort ett makro som anropar subrutin och om subrutin inte anropas någon gång,
så utelämnas den och inte kommer med i den generade koden.
Får bara tänka på att koden för subrutinen ska komma efter alla
anrop till den.
Så här ser det ut:
Kod: Markera allt
;*********************************************
VCall MACRO SubrutinAdress, SubrutinFinns
ifndef SubrutinFinns
#define SubrutinFinns x
endif
pagesel SubrutinAdress
CALL SubrutinAdress
pagesel $
endm
;*********************************************
; anrop
vcall h_mult, h_mult_
;----------------------------------
ifdef h_mult_
h_mult
nop
nop
nop
nop
nop
return
endif
;----------------------------------
Funkar, men lite klumpigt att behöva ange h_mult_ i varje anrop.
Jag har inte hittat nån snygg lösning på det. Någon som har nåt tips ?
Sen gjorde jag så att makrot (VACall) skulle känna av om det skulle
vara anrop där PCHLAT ändras. Det funkar bara om dom två extra NOP
är med, och då är det ju ingen mening med att välja sätt att anropa,
kan lika gärna ändra PCHLAT alltid (som VCall gör).
Om inte de två NOP är med så kommer felmeddelande:
Kod: Markera allt
Error[116] E:\TESTPAGE\TESTPAGEABS.ASM 183 : Address label duplicated or different in second pass (H_MULT)
Verkar som det finns en del begränsingar i vad man kan göra med makro.
Kan inte göra allt som är logiskt möjligt.
Kod: Markera allt
;*********************************************
VACall MACRO SubrutinAdress, SubrutinFinns
ifndef SubrutinFinns
#define SubrutinFinns x
endif
if ($ & 1800h) == ( SubrutinNamn & 1800h )
nop ; vill ej ha
nop ; vill ej ha
call SubrutinNamn
else
pagesel SubrutinNamn
call SubrutinNamn
pagesel $
endif
endm
;*********************************************
Postat: 6 december 2008, 00:26:19
av sodjan
Jag tror inte dina macron fungerar alls, varken med eller utan extra NOP's.
Har du provat ?
Postat: 6 december 2008, 09:16:35
av persika
Klart jag har provat dom, o dom funkar så som jag beskriver.
Något som är otydligt ?
Postat: 6 december 2008, 11:28:13
av bearing
Funkar, men lite klumpigt att behöva ange h_mult_ i varje anrop.
Jag har inte hittat nån snygg lösning på det. Någon som har nåt tips ?
Jag har inte provat, men jag tror det borde lösas genom att använda endast 1 argument till makrot, och använda det argumentet både på den platsen argument1 och argument2 är skrivna.
Postat: 6 december 2008, 12:30:33
av sodjan
> Något som är otydligt ?
Ja, det var inte tydligt om du bara hade provat att det byggde utan fel
eller om det även faktisk var provkört för att verifiera att koden
blev korrekt.
Jag ska göra ett litet egen test med din kod...
Postat: 6 december 2008, 12:59:47
av sodjan
Så, provade ditt VACall macro, men får det inte att bygga utan fel.
För min testkod, se sist i inlägget.
Först klagade den på "SubrutinNamn". Ska det inte vara "SubrutinAdress" !?
Eller hur fick du det att bygga med "SubrutinNamn" i macrot ?
Ändrade alla "SubrutinNamn" till "SubrutinAdress", men det ger nu istället:
Error[151] C:\DATA\PROJ\TEST\UNTITLED.ASM 11 : Operand contains unresolvable labels or is too complex
för raden "if ($ & 1800h) == ( SubrutinAdress & 1800h )"
Har du ett komplett test-case som fungerar (enligt din definition) ?
Kod: Markera allt
list p=16f886
#include <p16f886.inc>
;*********************************************
VACall MACRO SubrutinAdress, SubrutinFinns
ifndef SubrutinFinns
#define SubrutinFinns x
endif
if ($ & 1800h) == ( SubrutinAdress & 1800h )
nop ; vill ej ha
nop ; vill ej ha
call SubrutinAdress
else
pagesel SubrutinAdress
call SubrutinAdress
pagesel $
endif
endm
;*********************************************
RESET_VECTOR CODE 0x0000
goto Main ;go to start of main code
HI_INT_VECTOR CODE 0x0004
retfie
MAIN CODE
main
VACall sub1, sub1
VACall sub2, sub2
SUBS1 CODE h'0800'
sub1
nop
nop
return
SUBS2 CODE h'1000'
sub2
nop
nop
return
end
Postat: 6 december 2008, 17:23:53
av AndersG
Har gjort ett makro som anropar subrutin och om subrutin inte anropas någon gång,
så utelämnas den och inte kommer med i den generade koden.
Öh.. Är det inte det som
länkaren skall göra?

Postat: 6 december 2008, 18:31:58
av JockeE
Det gäller väl bara om den oanropade koden råkar finnas i en separat objektfil?
Postat: 6 december 2008, 19:14:18
av sodjan
Ja, jag tror att det fungerar så om rutinerna ligger i separata filer.
(Men å andra sidan så är det ju väldigt enkelt att testa för den intresserade...)
Postat: 6 december 2008, 19:24:05
av AndersG
Det gäller väl bara om den oanropade koden råkar finnas i en separat objektfil?
Ja, rent generellt. Efter att ha skummat vad MPLIB säger så verkar "granulariteten" vara objektfil. Således bör du sätta alla sådana funktioner i separata objektfiler och skapa ett bibliotek av dem.
Min kommentar var rent generellt att om man en gång bygger ett så stort projekt att man tappar överblick över vad som behövs och inte så kan man lika gärna använda de färdiga mekanismer som finns.
(Fn är min battmeter-kod just över 4000 rader och 3416 bytes)
Postat: 6 december 2008, 22:03:05
av persika
Det skulle vara fint om bara anropad kod kommer med i slutresultatet.
Om man t.ex har ett matematik-bibliotek med många rutiner i, add sub
mult div abs neg... osv. Det är onödigt att allt det kommer med bara
för att man vid ett tillfälle bara behöver "add" ex.vis. Minnesutrymmet
kan ju behövas till annat än bara fyllas upp med kod som aldrig används.
Att ha separata filer för varje rutin verkar jobbigt...
---
Har kunnat bygga denna kod för reloc-mod utan felmeddelande nu.
Dock, i makrot fick jag kommentera bort valet
om anropsätt (med eller utan ändring av PCHLAT).
Och sen ändrade jag parametrarna vid anropen av sub1 o sub2 till:
Sen lade jag även in att subbarna ska assembleras villkorligt.
Med detta går det att bygga koden och se resultatet i "program-memory"
Jag testade att ta bort anropet av sub1,
och då försvinner koden för sub1, som önskat.
Kod för reloc-mod:
Kod: Markera allt
list p=16f886
#include <p16f886.inc>
;*********************************************
VACall MACRO SubrutinAdress, SubrutinFinns
ifndef SubrutinFinns
#define SubrutinFinns x
endif
; if ($ & 1800h) == ( SubrutinAdress & 1800h )
; nop ; vill ej ha
; nop ; vill ej ha
; call SubrutinAdress
; else
pagesel SubrutinAdress
call SubrutinAdress
pagesel $
; endif
endm
;*********************************************
RESET_VECTOR CODE 0x0000
goto Main ;go to start of main code
HI_INT_VECTOR CODE 0x0004
retfie
MAIN CODE
main
VACall sub1, sub1_
VACall sub2, sub2_
SUBS1 CODE h'0800'
ifdef sub1_
sub1
nop
nop
return
endif
SUBS2 CODE h'1000'
ifdef sub2_
sub2
nop
nop
return
endif
end
I abs-mod så går det att få valet av anropsätt att funka också, nästan..
Men när man anropar sub2 från samma page (adress över 1000h) så blir det fel.
Här är koden för abs-mod:
Kod: Markera allt
list p=16f886
#include <p16f886.inc>
;*********************************************
VACall MACRO SubrutinAdress, SubrutinFinns
ifndef SubrutinFinns
#define SubrutinFinns x
endif
if ($ & 1800h) == ( SubrutinAdress & 1800h )
; nop ; vill ej ha
; nop ; vill ej ha
call SubrutinAdress
else
pagesel SubrutinAdress
call SubrutinAdress
pagesel $
endif
endm
;*********************************************
RESET_VECTOR org 0x0000
goto Main ;go to start of main code
HI_INT_VECTOR org 0x0004
retfie
MAIN org 0x0020
main
VACall sub1, sub1_
VACall sub2, sub2_
SUBS1 org h'0040'
ifdef sub1_
sub1
nop
nop
return
endif
SUBS2 org h'1000'
VACall sub2, sub2_ ; här blir det fel
; de 2 extra NOP i makrot behövs för detta ska bli rätt.
ifdef sub2_
sub2
nop
nop
return
endif
end