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

Offline 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?

Thanks in advance.
« Last Edit: January 31, 2011, 06:50:56 PM by lfa »

Offline 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

Offline 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.

Offline Bryant Keller

  • Forum Moderator
  • Full Member
  • *****
  • Posts: 360
  • Country: us
    • About Bryant Keller
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:

Code: (LinkedList.asm) [Select]
CPU 386
BITS 32

%macro StartList 1
%{1}:
%endmacro

%macro addNode 1+
%push
dd %[%%addr]
%{1}
%%addr:
%pop
%endmacro

%macro EndList 0
DD 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
%endmacro

SECTION .data

StartList myList
    addNode DD 1
    addNode DD 7
    addNode DD 5
    addNode DD 8
    addNode DD 12
    addNode DD 32
EndList

strFmt DB "%d", 10

EXTERN printf

SECTION .text
GLOBAL _start
_start:

for_each myList

    push eax
    push strFmt
    call printf ; display it
    add esp, 8

end_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] $ ./LinkedList
1
7
5
8
12
32
[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!  ;D

Regards,
Bryant Keller

About Bryant Keller
bkeller@about.me

Offline lfa

  • Jr. Member
  • *
  • Posts: 3
Re: NASM numeric equates (or: problems with %assign)
« Reply #4 on: February 03, 2011, 12:06:42 PM »
Thanks for the suggestion Bryant.

I should have clarified that the caller has been reworked to point at the dword containing the link address rather than the following cell; this makes walking the list simpler (and creating the list in .text very straightforward with the update_link macro).