Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

`TYPE` but then in NASM

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?

like image 924
Powarito Avatar asked Nov 30 '25 11:11

Powarito


1 Answers

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>
like image 77
Margaret Bloom Avatar answered Dec 02 '25 23:12

Margaret Bloom



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!