In assembly source, you can have the assembler calculate assemble-time constants like
msg: db "hello world", 10 ; 10 = ASCII newline
msglen equ $-msg
Then when you write mov edx, msglen
, it assembles to mov edx, imm32
with the constant substituted in. See How does $ work in NASM, exactly? for some examples.
But in the final machine-code, assemble-time constants have all become immediates or data constants. (e.g. ptr_and_length: dq msg, msglen
in the data or rodata section assembles into an address and a qword integer which is just there in the object file, not calculated at runtime from anything.)
(Assemble-time constants can also be used as repeat-counts in macros or other directives. (e.g.
times power imul eax, ecx
assembles to a block of that many imul
instructions.
power
is an integer constant defined with EQU. Or NASM %rep n
/ ... / %endrep
)
Or used in assemble-time expressions, so the size itself isn't literally present in the object file, just the result of some calculation based on it. (e.g. mov edx, msglen+2
or mov ecx, arrbytes/4
, the latter maybe as a bound for a loop that counts by dwords instead of bytes).