[Nasm-bugs] [Bug 3392837] %eval(pointer) can't expand in %warning/%error and %eval documentation typos
noreply-nasm at dev.nasm.us
noreply-nasm at dev.nasm.us
Tue Mar 7 08:48:03 PST 2023
https://bugzilla.nasm.us/show_bug.cgi?id=3392837
C. Masloch <pushbx at ulukai.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |pushbx at ulukai.org
--- Comment #3 from C. Masloch <pushbx at ulukai.org> ---
4.11 should not be changed unnecessarily as the %assign way works with older
NASM versions whereas %eval(...) does not.
Other than that, I believe the canonical way to expand things in
%warning/%error/%fatal is to use %assign to a temporary single-line macro. This
works in older NASM versions as well, if the expression being assigned
evaluates to a scalar.
%eval($) and %assign foo $ both do not work, as the dollar-sign refers to a
relocatable symbol, not a scalar. To obtain a scalar you can do label
arithmetic with a section start label to obtain a label delta, possibly adding
a displacement to simulate the section start offset. For example:
org 256
start:
...
end:
%assign size_smacro end - start + 256
Using an equate is also possible:
size_equate equ end - start + 256
But this won't on its own expand to a number in the preprocessor. However, you
can feed the equate (if it's done with the proper label arithmetic to be a
scalar) into %assign after the fact:
%assign size_equate_smacro size_equate
Resulting in the complete test case like this:
$ nasm -v
NASM version 2.16rc0 compiled on Sep 5 2022
$ cat test.asm
org 256
start:
times 26 db 0
end:
%assign size_smacro end - start + 256
size_equate equ end - start + 256
%assign size_equate_smacro size_equate
%warning size_smacro size_equate size_equate_smacro
$ nasm test.asm
test.asm:11: warning: 282 size_equate 282 [-w+user]
$
The label arithmetic is the same as needed to divide or shift a label delta (or
sum of label deltas), which is not allowed by NASM for non-scalar values. For
example, to gain a resident size in paragraphs you could use an expression for
an assembly operand like in:
mov dx, (resident_end - resident_start + 256 + 15) / 16
This is a related but somewhat separate problem to usage with %assign, but the
solution is similar. It's just that %assign additionally allows to propagate
scalar values back to the preprocessor from the assembler; note that this makes
the build fail if running in preprocess-only mode (switch -E).
As the NASM developers have oft repeated, the -f bin output format is
conceptually a linker internal to the NASM executable, so the assembler or
preprocessor part don't know that %eval($) is a "pointer value" (offset,
actually) that "should be known". It is simply a relocatable symbol value, that
the assembler/preprocessor cannot evaluate as a scalar.
For examples of label arithmetic, I'll refer to my application, lDebug.
Here's some defines that add several sections' sizes:
https://hg.pushbx.org/ecm/ldebug/file/b167070fdcc5/source/debug.asm#l246
%define CODESECTIONOFFSET
(100h+ldebug_data_entry_size+asmtable1_size+asmtable2_size)
%define INITSECTIONOFFSET
(CODESECTIONOFFSET+ldebug_code_size+ldebug_code2_size)
Here's something similar but with conversion to a different unit and back:
https://hg.pushbx.org/ecm/ldebug/file/b167070fdcc5/source/debug.asm#l265
%define BOOTDELTA (fromkib(kib(auxbuff_size * 2 \
+ historysegment_size \
+ datastack_size \
+ INITSECTIONOFFSET + 16)))
The single-line macros used here are from lmacros1.mac and use shifting to
convert between units, which is only allowed for scalars. Source:
https://hg.pushbx.org/ecm/lmacros/file/99b01fa65007/lmacros1.mac#l213
%idefine paras(b) ((b)+15>>4)
%idefine pages(b) ((b)+511>>9)
%idefine kib(b) ((b)+1023>>10)
...
%idefine fromkib(k) ((k)<<10)
Here's how to use one of the above defines, using one of the lmacros1 macros
yet again to shift so that another unit is calculated, also allowed only for
scalars:
https://hg.pushbx.org/ecm/ldebug/file/b167070fdcc5/source/debug.asm#l357
add ax, paras(INITSECTIONOFFSET)
push ax
push bx
retf
Here's a bit that declares an equate called init_size:
https://hg.pushbx.org/ecm/ldebug/file/b167070fdcc5/source/debug.asm#l7188
usesection INIT
align 16, db 0
init_size equ $-section.INIT.vstart
endarea init, 1
Finally, here's how to use the init_size equate with %assign and %warning (plus
an %if numeric conditional expression):
https://hg.pushbx.org/ecm/ldebug/file/b167070fdcc5/source/debug.asm#l7223
%assign __INITSIZE init_size
%if __INITSIZE > (64 * 1024)
%error init segment too large (%[__INITSIZE])
%endif
numdef SHOWINITSIZE, _DEFAULTSHOWSIZE
%if _SHOWINITSIZE
%warning init segment holds __INITSIZE bytes
%endif
--
You are receiving this mail because:
You are watching all bug changes.
You are on the CC list for the bug.
More information about the Nasm-bugs
mailing list