Assembler IFDEF / IFNDEF question
Hi All;
I'm needing some conditional assembly statements in a macro to effect the following:
············ If a LABEL has NOT already been defined, then define it (along with some code), else do not re-define it.
So when I define a macro like
Assign· Macro· Addr
···· ········· IFNDEF Addr
Addr············· somecode
········· ···· ENDIF
·········· Endm
Then the first time I invoke the macro with:
··········
··· ······ code1
······· ·· code2
····· ···· Assign· Name
········· ·code3
······· ·· code4
I would expect to get
······· ·· code1
····· ···· code2
Name····somecode
····· ···· code3
········· ·code4
Instead, the assembler appears not to·generate the macro's code as it believes the label ADDR is already assigned.·Using the opposite, IFDEF instead of the IFNDEF, generates the same result.
Am I mis-understanding the application of IFDEF and IFNDEF ?? or is this a bug.
Can anyone help me here, it is not·well explained in the documents.
Cheers,
Peter (pjv)
I'm needing some conditional assembly statements in a macro to effect the following:
············ If a LABEL has NOT already been defined, then define it (along with some code), else do not re-define it.
So when I define a macro like
Assign· Macro· Addr
···· ········· IFNDEF Addr
Addr············· somecode
········· ···· ENDIF
·········· Endm
Then the first time I invoke the macro with:
··········
··· ······ code1
······· ·· code2
····· ···· Assign· Name
········· ·code3
······· ·· code4
I would expect to get
······· ·· code1
····· ···· code2
Name····somecode
····· ···· code3
········· ·code4
Instead, the assembler appears not to·generate the macro's code as it believes the label ADDR is already assigned.·Using the opposite, IFDEF instead of the IFNDEF, generates the same result.
Am I mis-understanding the application of IFDEF and IFNDEF ?? or is this a bug.
Can anyone help me here, it is not·well explained in the documents.
Cheers,
Peter (pjv)
Comments
Assign Macro Addr
what = Addr
EndM
then watch the listing to see whats value.
What you are trying to do is pass the TEXT "Name" that is "N" "a" "m" "e" and the macro parameter system doesn't get that. The OLD SASM, prior to the SXKey IDE, passed all parameters as text then evaluated them after expanding the macro. Or passed them as values if you put "?" in front of them.
I could be wrong... It's been years since I've looked at this stuff.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
---
James Newton, Host of SXList.com
james at sxlist,com 1-619-652-0593 fax:1-208-279-8767
SX FAQ / Code / Tutorials / Documentation:
http://www.sxlist.com Pick faster!
So I've tried:
Device SX28, oschs3
IRC_SLOW
Freq 50 MHz
Assign·Macro Addr································· ;create an entry in an indirect jump table
·············· local MacroAddr···················· · ;try with a local variable
·············· MacroAddr = Addr··················· ;force a valuation
······················ ifndef MacroAddr········· ···;test for Addr already existing
······························ MainAddr = $········ ·;no, so remember where we came from
······························ org TableEnd········· ;append to the end of the jump table
I??Maddr···················page·MacroAddr······;the indirect entry in the jump table
··························· ···jmp·MacroAddr······· ;a single indirect paged entry to the desired address in main
··························· ···TableEnd = $······· ··;update table end
·······························org·MainAddr········· ;restore Main address
···················· ··endif·························· ··;end of if
·············· endm··································· ;end of macro
····················· ·org·$10
TableEnd·= $
Main················ org·$50
······················ mov·w,#1···················· ·;arbitrary code
····················· ·Assign·There················· ;create indirect entry via the macro if not already existing
There············· ·mov·w,#2··················· ··;more arbitrary code
····················· ·mov·w,#3····················· ;more arbitrary code
··················· · ·Assign·There················· ;assign again, but it should not perform this by skipping past it with the ifndef directive in the macro
····················· ·mov·w,#3···················· ·;more arbitrary code
and I can't get it to cooperate. Even if I force the value to be passed using the ? operator.
Would you mind having a poke at this for me ?
What I'm trying to do is to use a macro to create an indirect jump table, and have multiple references to any address use only a single entry in the table.
Cheers,
Peter (pjv)
Post Edited (pjv) : 1/22/2008 6:24:33 AM GMT
Here is a macro from my dynamic library. Whenever I use macros I always look
back into that file as it demonstrates the most useful macro possibilities.
_lib_queue_var··macro·name, size
· tempsize = size+2
if ((data + tempsize - 1) & $F0) != (data & $F0)
error "queue buffer too large, crossing rambank boundary"
endif
ifndef vp_queue
vp_queue
endif
···org·data
expand
??name??··equ·$
queue_??name??_sizenum·ds·1
queue_??name??_headtail·ds·1
queue_??name??_buffer·ds·size
noexpand
data··=·$
endm
The key here is to use the parameter, enclosed in ??
in your case that would be
??addr??
I attached my file so you can inspect the generated listing as well.
regards peter
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
---
James Newton, Host of SXList.com
james at sxlist,com 1-619-652-0593 fax:1-208-279-8767
SX FAQ / Code / Tutorials / Documentation:
http://www.sxlist.com Pick faster!
In its simplest form, all I'm trying to do is: If an instruction statement starting with a particular label has not yet been entered into my source code (that is a proper use of "IFNDEF" of the lable as I understand it), then create the line, otherwise do nothing and exit the macro.
Like:
Assign··· macro Name············ ;create a macro
················· ifdef I??Name····· ;test for the modified parameter passed already exists
············ exitm····················· ;if so then bail out
············ else······················· ;otherwise
I??Name······· jmp Name········· ;create this label from the parameter passed
············ endm····················· ;done
And when I invoke the macro once, this works OK. It's when I invoke it subsequent times that I get a "redefine symbol" message. What I need the macro to realize it has already issued the statement in the first instance, and from that point on it should not attempt to issu it again. This way I could create a very nice jump table sort of automatically.
I just can't get it to be happy after the first invocation...... help??
Cheers,
Peter (pjv)
Assign··· macro Name············ ;create a macro
················· ifdef I??Name??····· ;test for the modified parameter passed already exists
············ exitm····················· ;if so then bail out
············ else······················· ;otherwise
I??Name??······· jmp ??Name??········· ;create this label from the parameter passed
············ endm····················· ;done
regards peter
Yes, I have literally copied your post and imported into SX and it does not work.
Also, I believe the trailing set of pasting operator (??) is of no consequence as it has nothing to concatenate to.
AAARRRGGGG!!
Cheers,
Peter (pjv)
Attached program generates this listing:
···· 1· 07F8· 0F7F····· device········· SX28,oschs1,turbo,stackx,optionx······· ;sx device options
···· 2· =00000000······ irc_cal········ IRC_SLOW
···· 3· =02FAF080······ freq··········· 50_000_000····························· ;cpu frequency
···· 4· 07FF· 0A07····· reset·········· main
···· 5·················
···· 6················· Assign· macro·· Name··········· ;create a macro
···· 7···················· ifndef I??Name??············ ;test for the modified parameter passed already exists
···· 8················· I??Name??
···· 9························· jmp···· @??Name??······ ;create this label from the parameter passed
··· 10···················· endif
··· 11················· endm··························· ;done
··· 12·················
··· 13· =00000000·············· org 0
··· 14················· Assign rx1
··· 15·············· m···· ifndef Irx1········· ;test for the modified parameter passed already exists
··· 16·············· m· Irx1
··· 17·············· m········· jmp···· @rx1··· ;create this label from the parameter passed
··· 18·············· m···· endif
··· 20················· Assign rx2
··· 21·············· m···· ifndef Irx2········· ;test for the modified parameter passed already exists
··· 22·············· m· Irx2
··· 23·············· m········· jmp···· @rx2··· ;create this label from the parameter passed
··· 24·············· m···· endif
··· 26· =00000004······ rx1
··· 27· 0000· 0C01············· mov···· w,#1
··· 28· =00000005······ rx2
··· 29· 0001· 01C4············· add···· w,fsr
··· 30· 0002· 000C············· ret
··· 31· =00000007······ main
··· 32· 0003· 0A07············· jmp···· main
Cross Reference
10 symbols
Symbol··························· Type·· Value····· Line
__SASM··························· DATA·· 00000001·· 0000
__SX_FREQ························ DATA·· 02FAF080·· 0003
__SX_IRC_CAL····················· DATA·· 00000000·· 0002
__SX_RESET······················· RESB·· 00000A07·· 0004
fsr······························ RESV·· 00000004·· 0029
Irx1····························· ADDR·· 00000000·· 0016
Irx2····························· ADDR·· 00000002·· 0022
main····························· ADDR·· 00000007·· 0031
rx1······························ ADDR·· 00000004·· 0026
rx2······························ ADDR·· 00000005·· 0028
According to the symbol table, Irx1 and Irx2 are created at the right addresses.
regards peter
Look at this listing
···· 1· 07F8· 0F7F····· device········· SX28,oschs1,turbo,stackx,optionx······· ;sx device options
···· 2· =00000000······ irc_cal········ IRC_SLOW
···· 3· =02FAF080······ freq··········· 50_000_000····························· ;cpu frequency
···· 4· 07FF· 0A05····· reset·········· main
···· 5················· expand
···· 6·················
···· 7················· Assign2 macro·· Name··········· ;create a macro
···· 8················· ifndef I??Name
···· 9························· org···· $
··· 10················· I??Name
··· 11························· jmp···· @Name·· ;create this label from the parameter passed
··· 12················· else
··· 13························· org···· $
··· 14················· endif
··· 15················· endm··························· ;done
··· 16·················
··· 17················· Assign· macro·· Name··········· ;create a macro
··· 18················· ifndef I??Name········· ;test for the modified parameter passed already exists
··· 19················· I??Name
··· 20························· jmp···· @??Name ;create this label from the parameter passed
··· 21················· endif
··· 22················· endm··························· ;done
··· 23·················
··· 24· =00000000·············· org 0
··· 25················· ;Assign rx1
··· 26················· ;Assign rx2
··· 27················· Assign2 rx1
··· 28·············· m· ifndef Irx1
··· 29·············· m········· org···· $
··· 30·············· m· Irx1
··· 31·············· m········· jmp···· @rx1··· ;create this label from the parameter passed
··· 32·············· m· else
··· 33· =00000000··· m········· org···· $
··· 34·············· m· endif
··· 36· =00000002······ rx1
··· 37· 0000· 0C01············· mov···· w,#1
··· 38· =00000003······ rx2
··· 39· 0001· 01C4············· add···· w,fsr
··· 40· 0002· 000C············· ret
··· 41· =00000005······ main
··· 42· 0003· 0A05············· jmp···· main
Cross Reference
9 symbols
Symbol··························· Type·· Value····· Line
__SASM··························· DATA·· 00000001·· 0000
__SX_FREQ························ DATA·· 02FAF080·· 0003
__SX_IRC_CAL····················· DATA·· 00000000·· 0002
__SX_RESET······················· RESB·· 00000A05·· 0004
fsr······························ RESV·· 00000004·· 0039
Irx1····························· ADDR·· 00000000·· 0030
main····························· ADDR·· 00000005·· 0041
rx1······························ ADDR·· 00000002·· 0036
rx2······························ ADDR·· 00000003·· 0038
The label Irx1 does not exist when calling Assign2, so it gets created (but no code).
On the second pass the label exist and the·else clause is executed (does generate code).
regards peter
but the label only in the 'if' section, and an org in the 'else' section.
···· 1· 07F8· 0F7F····· device········· SX28,oschs1,turbo,stackx,optionx······· ;sx device options
···· 2· =00000000······ irc_cal········ IRC_SLOW
···· 3· =02FAF080······ freq··········· 50_000_000····························· ;cpu frequency
···· 4· 07FF· 0A07····· reset·········· main
···· 5················· expand
···· 6·················
···· 7················· Assign· macro·· Name··········· ;create a macro
···· 8················· ifndef I??Name········· ;test for the modified parameter passed already exists
···· 9················· I??Name
··· 10························· jmp···· @??Name ;create this label from the parameter passed
··· 11················· else
··· 12························· org···· I??Name
··· 13························· jmp···· @??Name ;create this label from the parameter passed
··· 14················· endif
··· 15················· endm··························· ;done
··· 16·················
··· 17· =00000000·············· org 0
··· 18················· Assign rx1
··· 19·············· m· ifndef Irx1············ ;test for the modified parameter passed already exists
··· 20·············· m· Irx1
··· 21·············· m········· jmp···· @rx1··· ;create this label from the parameter passed
··· 22·············· m· else
··· 23· =00000000··· m········· org···· Irx1
··· 24· 0000· 0010·· m········· jmp···· @rx1··· ;create this label from the parameter passed
······· 0001· 0A04
··· 25·············· m· endif
··· 27················· Assign rx2
··· 28·············· m· ifndef Irx2············ ;test for the modified parameter passed already exists
··· 29·············· m· Irx2
··· 30·············· m········· jmp···· @rx2··· ;create this label from the parameter passed
··· 31·············· m· else
··· 32· =00000002··· m········· org···· Irx2
··· 33· 0002· 0010·· m········· jmp···· @rx2··· ;create this label from the parameter passed
······· 0003· 0A05
··· 34·············· m· endif
··· 36· =00000004······ rx1
··· 37· 0004· 0C01············· mov···· w,#1
··· 38· =00000005······ rx2
··· 39· 0005· 01C4············· add···· w,fsr
··· 40· 0006· 000C············· ret
··· 41· =00000007······ main
··· 42· 0007· 0A07············· jmp···· main
Cross Reference
10 symbols
Symbol··························· Type·· Value····· Line
__SASM··························· DATA·· 00000001·· 0000
__SX_FREQ························ DATA·· 02FAF080·· 0003
__SX_IRC_CAL····················· DATA·· 00000000·· 0002
__SX_RESET······················· RESB·· 00000A07·· 0004
fsr······························ RESV·· 00000004·· 0039
Irx1····························· ADDR·· 00000000·· 0020
Irx2····························· ADDR·· 00000002·· 0029
main····························· ADDR·· 00000007·· 0041
rx1······························ ADDR·· 00000004·· 0036
rx2······························ ADDR·· 00000005·· 0038
regards peter
but the entry is only generated once.
···· 1· 07F8· 0F7F····· device········· SX28,oschs1,turbo,stackx,optionx······· ;sx device options
···· 2· =00000000······ irc_cal········ IRC_SLOW
···· 3· =02FAF080······ freq··········· 50_000_000····························· ;cpu frequency
···· 4· 07FF· 0A07····· reset·········· main
···· 5················· expand
···· 6·················
···· 7· =00000000······ Irx1value = 0·· ;define variables for possible labels
···· 8· =00000000······ Irx2value = 0
···· 9·················
··· 10················· Assign· macro·· Name··········· ;create a macro
··· 11················· if I??Name??value == 0
··· 12················· I??Name??value = 1············· ;prevent multiples
··· 13················· I??Name
··· 14························· jmp···· @??Name ;create this label from the parameter passed
··· 15················· endif
··· 16················· endm··························· ;done
··· 17·················
··· 18· =00000000·············· org 0
··· 19················· Assign rx1
··· 20·············· m· if Irx1value == 0
··· 21· =00000001··· m· Irx1value = 1·········· ;prevent multiples
··· 22· =00000000··· m· Irx1
··· 23· 0000· 0010·· m········· jmp···· @rx1··· ;create this label from the parameter passed
······· 0001· 0A04
··· 24·············· m· endif
··· 26················· Assign rx2
··· 27·············· m· if Irx2value == 0
··· 28· =00000001··· m· Irx2value = 1·········· ;prevent multiples
··· 29· =00000002··· m· Irx2
··· 30· 0002· 0010·· m········· jmp···· @rx2··· ;create this label from the parameter passed
······· 0003· 0A05
··· 31·············· m· endif
··· 33················· Assign rx1····· ;create entry from 2nd location
··· 34·············· m· if Irx1value == 0
··· 35·············· m· Irx1value = 1·········· ;prevent multiples
··· 36·············· m· Irx1
··· 37·············· m········· jmp···· @rx1··· ;create this label from the parameter passed
··· 38·············· m· endif
··· 40·················
··· 41· =00000004······ rx1
··· 42· 0004· 0C01············· mov···· w,#1
··· 43· =00000005······ rx2
··· 44· 0005· 01C4············· add···· w,fsr
··· 45· 0006· 000C············· ret
··· 46· =00000007······ main
··· 47· 0007· 0A07············· jmp···· main
··· 48·················
Cross Reference
12 symbols
Symbol··························· Type·· Value····· Line
__SASM··························· DATA·· 00000001·· 0000
__SX_FREQ························ DATA·· 02FAF080·· 0003
__SX_IRC_CAL····················· DATA·· 00000000·· 0002
__SX_RESET······················· RESB·· 00000A07·· 0004
fsr······························ RESV·· 00000004·· 0044
Irx1····························· ADDR·· 00000000·· 0022
Irx1value························· VAR·· 00000001·· 0007
Irx2····························· ADDR·· 00000002·· 0029
Irx2value························· VAR·· 00000001·· 0008
main····························· ADDR·· 00000007·· 0046
rx1······························ ADDR·· 00000004·· 0041
rx2······························ ADDR·· 00000005·· 0043
The idea is to create compile variables for each possible label, initialized to 0.
Inside Assign, those variables will be set to 1, so a second call with an identical name
does not generate code.
regards peter
No, that still does not work. Perhaps I'm not explaining myself well enough.
I wish to create a macro (several in fact, one for indirect jump, one for indirect call, and one for indirect statejump, and perhaps more) that I will name IJump, ICall etc.
These macros will each have one parameter; the label of the address were the jump is to end up. What the macro is to do, is test for a modified label (that would be the·name·of the entry in the jump table), particularly IPARAM where the parameter passed to the macro is pre-pended with something to differentiate it from the target jump address (so address FOUR is modified to IFOUR), and if that label does not exist, then append an entry in the jump table on page zero for address FOUR passed to the macro IJump. Each entry in the table has the modified target name as a label with a page and the jump address of the target. Naturally the macro needs to restore the program counter with an org to the value it had at the point of the macro call.
I can get this to work for the first instance I make the macro call to any target address, but subsequent calls to the SAME address will not work. Naturally I wish to have only one entry in my jump table per jump location, but be able to access that multiple times, and from anywhere.
So my issue is the multiple call situation. At present (that is without this feature) I have to manually remember whether or not the indirect entry has already been entered, and I thought the macro should be able to do this for me.
Thanks for your interest, and putting up with my ranting.
Cheers,
Peter (pjv)
Post Edited (pjv) : 1/25/2008 8:14:46 PM GMT
There is also a working macro for the OLD version of SASM that includes a subroutine inline the first time and then calls it at that location each following time in the old newsletter article.
It's fun to see new people work with macros though...
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
---
James Newton, Host of SXList.com
james at sxlist,com 1-619-652-0593 fax:1-208-279-8767
SX FAQ / Code / Tutorials / Documentation:
http://www.sxlist.com Pick faster!
I've looked through all that and was quite overwhelmed.... not sure I can grasp it all, and to know the nuances. You've done a tremendous amount of work.
However, I thought my question was quite simple (perhaps the answer is not) and I'd like to approach it in the manner I've described if at all possible, because not having to pre-think the macro instances will lend itself better to the RTOS where I plan to use this.
If you could lend a hand in that direction it would be appreciated, or at least tell me if it can't be done that way.
In the mean time I will try to see where I can find "the old newsletter article", and an OLD verson of SASM.
Cheers,
Peter (pjv)