? i LST-fil

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg 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... :-)
Användarvisningsbild
persika
EF Sponsor
Inlägg: 1541
Blev medlem: 31 juli 2006, 22:14:37
Ort: Österlen, Skåne

Inlägg 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.
Användarvisningsbild
AndersG
EF Sponsor
Inlägg: 9127
Blev medlem: 25 februari 2008, 17:10:58
Ort: Mariehamn
Kontakt:

Inlägg 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
Användarvisningsbild
vfr
EF Sponsor
Inlägg: 3515
Blev medlem: 31 mars 2005, 17:55:45
Ort: Kungsbacka

Inlägg 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.
Användarvisningsbild
persika
EF Sponsor
Inlägg: 1541
Blev medlem: 31 juli 2006, 22:14:37
Ort: Österlen, Skåne

Inlägg 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
;*********************************************

sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Jag tror inte dina macron fungerar alls, varken med eller utan extra NOP's.
Har du provat ?
Användarvisningsbild
persika
EF Sponsor
Inlägg: 1541
Blev medlem: 31 juli 2006, 22:14:37
Ort: Österlen, Skåne

Inlägg av persika »

Klart jag har provat dom, o dom funkar så som jag beskriver.
Något som är otydligt ?
bearing
Inlägg: 11677
Blev medlem: 2 mars 2006, 01:01:45
Ort: Ängelholm

Inlägg 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.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg 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...
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg 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
Användarvisningsbild
AndersG
EF Sponsor
Inlägg: 9127
Blev medlem: 25 februari 2008, 17:10:58
Ort: Mariehamn
Kontakt:

Inlägg 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? ;)
Användarvisningsbild
JockeE
Inlägg: 330
Blev medlem: 4 augusti 2004, 08:46:50

Inlägg av JockeE »

Det gäller väl bara om den oanropade koden råkar finnas i en separat objektfil?
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg 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...)
Användarvisningsbild
AndersG
EF Sponsor
Inlägg: 9127
Blev medlem: 25 februari 2008, 17:10:58
Ort: Mariehamn
Kontakt:

Inlägg 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)
Användarvisningsbild
persika
EF Sponsor
Inlägg: 1541
Blev medlem: 31 juli 2006, 22:14:37
Ort: Österlen, Skåne

Inlägg 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:

Kod: Markera allt

	VACall		sub1, sub1_
	VACall		sub2, sub2_
Sen lade jag även in att subbarna ska assembleras villkorligt.

Kod: Markera allt

	ifdef sub1_
sub1
	nop
	nop
	return
	endif

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
Skriv svar