3.9 Local Labels
NASM gives special treatment to symbols beginning with a period. A label beginning with a single period is treated as a local label, which means that it is associated with the previous non-local label. So, for example:
label1 ; some code
.loop
; some more code
jne .loop
ret
label2 ; some code
.loop
; some more code
jne .loop
ret
In the above code fragment, each JNE instruction jumps to the line immediately before it, because the two definitions of .loop are kept separate by virtue of each being associated with the previous non-local label...
No mention of the use of a :(colon) nor that each label will produce warning: label alone on a line without a colon might be in error
Right. So the manual contains examples that may make it more difficult to find actual errors.
4.3 Multi-Line Macros: %macro
….
Multi-line macros, like single-line macros, are case-sensitive, unless you define them using the alternative directive %imacro.
My Deduction: If Multi-line macros and single-line macros are defined with %macro directive they are case sensitive!
Therefore ENDP is not equal to ENDp and should give error: symbol `ENDp' undefined
But it does display "warning: label alone on a line without a colon might be in error". "ENDp" (alone on a line) is not a
usage of a symbol named "ENDp", it is the definition. (Multiple such lines (if in the same case) will cause an error for re-defining the label.) Arguably, NASM could provide an option to make such a label definition an error. But it should not display "symbol undefined" in that case.
or something like this
%define label LABEL:
label
mov eax,1
jmp LABEL
;jmp label <-- error: invalid combination of opcode and operands
throws an error when jmp label
The colon is only used for defining a label, not for referring to it. Therefore:
label:
jmp label
jmp LABEL ; error because LABEL is not defined
%macro defint 0
[section .data]
db 10
%endm
defInt should not produce warning: label alone on a line without a colon might be in error. Nasm should be able to distinguish between labels and macros and should be treated as Symbol not defined if otherwise
No macro or label of the name "defInt" exists with that macro definition. Therefore, interpreting it as a label definition is right (if error-prone).
4.3.1 Overloading Multi-Line Macros
As with single-line macros, multi-line macros can be overloaded by defining the same macro name several times with different numbers of parameters. This time, no exception is made for macros with no parameters at all. So you could define:
%imacro End 1
;some code
%endm
%imacro END 1
;some code
%endm
and invoked
ENd 1
EnD 2
eND 3
compiles without error or warning
I do not know if this is a bug or not
Guess it should display the "re-defining macro" warning (it doesn't), but all of the invocations are correct. Note that you defined a case-insensitive macro (%
imacro) therefore its name is matched case insensitively.
I believe the answer may be in this statement:
Quote from the docs: NASM is very simple by comparison: everything is a label.
No, I believe this statement refers to memory referencing operands. In that section of the manual NASM's semantics are compared to other assemblers; these other assemblers know several kinds of labels. This issue is not relevant here.
Therefore:
label1 ;could be a label could be a macro invocation with 0 parameters? We don't know so we throw a error and treat it as an orphan label.
Yes, except NASM only throws a warning for compatibility.
If Label: or .label: would have to be defined like this then Enp in my original example could not possibly be an orphan label? And error: symbol `ENDp' undefined could be genereated without ambiguity.
No, "orphan label" means a label where you
missed the colon. Therefore, if the colon was enforced orphan labels would not exist. As I mentioned, the missing colon will only cause a warning for compatibility.
But
if you define every real label with a colon, then you can treat every "orphan label" warning to indicate that you have to investigate that particular line, because either you missed the colon (if it is really intended to be a label) or you misspelled something else (an instruction, a macro invocation). Like in your "ENDp" example.
You are free to define labels without colons. But every such label will then display the "orphan label" warning (if that warning is enabled) which makes the warning a lot less useful. Therefore, I would advise you to use colons for defining labels.
%idefine ADDR dword
%imacro addr 1
mov eax,ff
%endm
mov eax,addr val ;<-- should give error: comma, colon or end of line expected
mov eax,ADDR val
This is a short and meaningless example that compiles without error and runs but both variants produce the same code (mov eax,dword val)
In this case, the position of the "addr" and "ADDR" terms in your instruction indicate that it cannot be a multi-line macro (%macro) invocation. Therefore, the preprocessor treats it as a single-line macro (%define) Actually, it is sufficient to say that single-line macros (%define) are processed first in any given line. Therefore, your (case-insensitive) single-line macro was expanded. The multi-line macro is never expanded.
About a year ago I have made drastic changes to my macro system that are not backward compatible. I'm still in the tweaking stage and need to jump back and forth between implementations without modifying code or defines so the old proggies continue to work. Simple solution would be to have old macro version in lowercase and new version in upper case in the same file. And then using Proc for new procedures vers proc for old procedures.
If by "simple", you mean "failure-prone", yes that would be the simple solution. But the preprocessor does allow you to do that anyway:
%macro Proc 0+
%warning New version of the procedure macro.
%endm
%macro proc 0+
%warning Old version of the procedure macro.
%endm
proc
proc
Proc