I know there are SIZEOF
and TYPE
in MASM, but what about NASM? As I found, it doesn't have these.
For example:
array dw 1d, 2d, 3d, 4d
arrSize db $-array ;4 elements * 2 bytes (size of one element) = 8 bytes
This is how I can make alternative of SIZEOF array
in NASM. If I want the number of array elements, I can divide arrSize by 2 (if array elements are words). But if array elements are double words (32-bit), I need to divide by 4.
Is there an alternative for TYPE
from MASM in NASM? If not, how can I make the program determine the size of the element itself?
NASM keeps its directives simple and with minimal automagic features.
It doesn't seem to be corresponding directives for the MASM type
, sizeof
and length
operators.
Luckily, NASM took a much better approach than introducing heavy typing in assembly: it developed a very rich and expressive macro system.
Consider this simple macro:
;array <label>, <item directive>, <items>
%macro array 4-*
%1: %2 %{3} ;label: db/dw/dd/... <firstItem>
%%second: %2 %{4:-1} ;Local label (to get item size) and rest of the items
%1_size EQU $ - %1 ;Size of the array in bytes (here - label)
%1_type EQU %%second - %1 ;Size of an item in bytes (second - label)
%1_lengthof EQU %1_size / %1_type ;Number of items (size of array / size of item)
%endmacro
You can use it like array my_array, dd, 1, 2, 3
. Not exactly like my_array dd 1, 2, 3
but close.
Then you have:
my_array_size
. Size of the array in bytes.my_array_type
. Size of one array item in bytes.my_array_lengthof
. Number of items in the array.You can tweak the macro to adapt it to your personal style (eg: to generate my_array.size
and similar or make arrdb
, arrdw
, arrdd
variants that implicitly take the item declaration directive).
Example:
BITS 32
;array <label>, <item directive>, <items>
%macro array 4-*
%1: %2 %{3} ;label: db/dw/dd/... <firstItem>
%%second: %2 %{4:-1} ;Local label, to get item size
%1_size EQU $ - %1 ;Size of the array in bytes (here - label)
%1_type EQU %%second - %1 ;Size of an item in bytes (second - label)
%1_lengthof EQU %1_size / %1_type ;Number of items (size of array / size of item)
%endmacro
;To test, use ndisam -b32
mov eax, my_array_size
mov eax, my_array_type
mov eax, my_array_lengthof
mov eax, DWORD [my_array]
;The array (ignore on output from ndisasm)
array my_array, dd, 1, 2, 3
Using ndisam -b32
on the generated binary:
00000000 B80C000000 mov eax,0xc
00000005 B804000000 mov eax,0x4
0000000A B803000000 mov eax,0x3
0000000F A114000000 mov eax,[0x14]
00000014 <REDACTED GARBAGE>