### Author Topic: NASM numeric equates (or: problems with %assign)  (Read 3896 times)

#### lfa

• Jr. Member
• Posts: 3
##### NASM numeric equates (or: problems with %assign)
« on: January 31, 2011, 05:58:53 PM »
Hi all,

I'm trying to figure out a way of achieving the following (MASM snippet) in NASM:

Code: [Select]
`link = 0; ...construct:  dd link  link = \$; ...`
where the assignment of \$ to link will be evaluated multiple times and employed in the construction of a linked list.

I initially thought that I could use %assign for this purpose, but read in the manual that

Quote
The expression passed to %assign is a critical expression (see section 3.8 ), and must also evaluate to a pure number (rather than a relocatable reference such as a code or data address, or anything involving a register).

Any ideas on how I might go about solving this in NASM?

« Last Edit: January 31, 2011, 06:50:56 PM by lfa »

#### cm

• Jr. Member
• Posts: 65
##### Re: NASM numeric equates (or: problems with %assign)
« Reply #1 on: January 31, 2011, 07:04:36 PM »
There are several ways to solve that, but I would probably do it like this:

Code: [Select]
`%define link 0     ; or %assign, doesn't matter in this case; ...construct:%define link construct; ...`
This assumes that your code really contains a label like "construct" each time that you want to re-define link. So, a second re-definition would have to look somewhat like this (as labels must be unique, you cannot re-use the label "construct"):

Code: [Select]
`second_construct:%define link second_construct; ...`
It might require less typing or be easier to implement in your code to use macro-local labels or context-local labels. For example, using macros along the former:

Code: [Select]
` %define link 0 %macro constructlabel 0%%construct:%define link %%construct %endmacro; ... constructlabel; ... constructlabel; ...`
Notice how the macro is used multiple times, but in fact defines a different label each time. "link" is re-defined (in the preprocessor) to the last defined label's name. If you use a macro to create your constructs (the "; ..." parts) anyway, then you could include the two lines in my example's macro at the beginning of your macro instead of using two separate macros.

This mechanism could be implemented using context-local labels instead.
C. Masloch

#### lfa

• Jr. Member
• Posts: 3
##### Re: NASM numeric equates (or: problems with %assign)
« Reply #2 on: January 31, 2011, 09:21:33 PM »
Thanks for your suggestions cm; here's what I've ended up with:

Code: [Select]
`%define link 0%macro update_link 0%%update_link:  dd link  %define link %%update_link%endmacro`
Nice and compact.

#### Bryant Keller

• Forum Moderator
• Full Member
• Posts: 360
• Country:
##### Re: NASM numeric equates (or: problems with %assign)
« Reply #3 on: February 03, 2011, 07:28:15 AM »
Not quite, the masm code is using 'link = \$' to set link to the address after the dd, so what you are actually creating is something like:

`CPU 386BITS 32%macro StartList 1%{1}:%endmacro%macro addNode 1+%pushdd %[%%addr]%{1}%%addr:%pop%endmacro%macro EndList 0DD 0    ; NULL TERMINATOR%endmacro%macro for_each 1%push _FOR_EACH_    pushad    mov edi, %{1}%\$start_of_for:    mov eax, [edi]    or eax, eax    jz %[%\$end_of_for]    push edi    mov eax, [edi+4]%endmacro%macro end_for 0    pop edi    mov edi, [edi]    jmp %[%\$start_of_for]%\$end_of_for:    popad%pop%endmacroSECTION .dataStartList myList    addNode DD 1    addNode DD 7    addNode DD 5    addNode DD 8    addNode DD 12    addNode DD 32EndListstrFmt DB "%d", 10EXTERN printfSECTION .textGLOBAL _start_start:for_each myList    push eax    push strFmt    call printf ; display it    add esp, 8end_for    xor eax, eax    xor ebx, ebx    inc eax    int 80h`
The code which scans the linked list is Linux/GlibC dependent, but the macros should work on any platform.

Code: (console) [Select]
`[bkeller@localhost ~/temp] \$ nasm -f elf -o LinkedList.o LinkedList.asm[bkeller@localhost ~/temp] \$ gcc -nostartfiles LinkedList.o -o LinkedList[bkeller@localhost ~/temp] \$ ./LinkedList17581232[bkeller@localhost ~/temp] \$ `
WARNING: Not a whole lot of thought was put into this example, it's by no means meant to be optimized (in fact, for_each is down-right ugly).  But at least it works!

Regards,
Bryant Keller