my error mate, I used define instead of idefine so it wasn't recognizing the change in case:

%imacro ASSUME 2
        %ifidni %2, NOTHING
                %undef %{1}.
        %else
                %idefine %{1}.(_x_) %{1} + %{2} %+ . %+ _x_
        %endif
%endm


This should fix the problem.
Posted on 2009-10-02 02:12:45 by Synfire
Had to change Macro to:
%imacro ASSUME 2
%ifidni %2, NOTHING
%undef %{1}.
%else
%idefine %{1}.(x) %{1} + %{2}. %+ x
%endif
%endm


Haven't fully tested the macro yet but so far it works ok.

Thank you very much for all your help and suggestion

Klod
Posted on 2009-10-02 22:42:15 by Klod
To Synfire
I have spent a couple of hours playing around with the Assume macro and it is not working correctly.
The alteration I made to the macro in my previous post, worked only because I had an argument  x. All successive invocations produced a valid result, the value of the .x  argument.
mov     WORD , AX

will throw the following error:
symbol `DOUBLEWORD._x_' undefined


The preprocessor will define the following symbol:
highlow + DOUBLEWORD._x_

It appears theat the %idefine  %{1}.(_x_)  %{1} + %{2}. %+ _x_ treats the placeholder (_x_) as a string and not as a variable.

Would you have any suggestions how this could be worked out?

Regards
Klod


Posted on 2009-10-04 00:20:42 by Klod
Use the one I posted above. The original one I posted has a few errors because I just typed it out from memory, the last one I posted was actually from my macro.inc file. You'll notice a few differences, it does work, see below:

	BITS 32

%imacro ASSUME 2
        %ifidni %2, NOTHING
                %undef %{1}.
        %else
                %idefine %{1}.(_x_) %{1} + %{2} %+ . %+ _x_
        %endif
%endm

STRUC HighLow
.High RESW 1
.Low RESW 1
ENDSTRUC

SECTION .data

ddBlah DD 123456789
strFmt DB `High Word: %d\nLow Word: %d\n`, 0

SECTION .text

Global main
main: Push Ebp
Mov Ebp, Esp

Xor Eax, Eax
Xor Ebx, Ebx

ASSUME ddBlah, HighLow
Mov Ax,
Mov Bx,
ASSUME ddBlah, NOTHING

Push Eax
Push Ebx
Push DWORD strFmt
Extern printf
Call printf
Add Esp, (3*4)
Leave
Ret


built with 'nasm -f elf test.asm; gcc -o test test.o' on linux.
Posted on 2009-10-04 02:33:48 by Synfire
Thanks Synfire for your code example I could not get it to work as you posted it above. I was digging through the docs and found
4.1.3 Concatenating Single Line Macro Tokens: %+
I think this must have been your inspiration for your assume macro. I do not have linux installed on my machine, so I modified your program to produce a working program that works. Here is the code:
%define ddBlah(x)  ddBlah+HighLow %+x
EXTERN wsprintfA
EXTERN ExitProcess
EXTERN MsgBox

STRUC HighLow
.High RESW 1
.Low RESW 1
ENDSTRUC

SECTION .data

ddBlah DD 123456789
strFmt DB `High Word: %d\nLow Word: %d\n`, 0
buffer TIMES 1024 db 0
caption db 'Testing',0
SECTION .text

Global Start
Start:
movzx eax,WORD ;access the structure with Nasm notation
movzx ebx,WORD ; to prove out the program
Mov Ax, ddBlah(Low) ;assembled -e option Mov Ax, ddBlah+HighLowLow
Mov Bx, ddBlah(.High) ;assembled -e option Mov Bx, ddBlah+HighLow.High This is what I wanted

Push Eax
Push Ebx
Push DWORD strFmt
push dword buffer
Call wsprintfA
push caption
push buffer
call MsgBox
push 0
call ExitProcess

;Radasm IDE 3,O,$B\NASM -Ox -fwin32 ,2
;$.exe,O,$B\GoLink.EXE @$B\GFL.txt /debug coff /entry Start ,3


These are the two errors I get for above code sample
MacroTest.asm:24: error: symbol `HighLowLow' undefined        ;self explanatory
MacroTest.asm:25: error: COFF format does not support non-32-bit relocations  ;see below

As can be seen from the -e assembly Mov Bx, ddBlah(.High) assembled to  Mov Bx, ddBlah+HighLow.High, what I wanted but I get MacroTest.asm:25: error: COFF format does not support non-32-bit relocations

It appears there is an incompatibility between the docs and Windows version of NAsm. because clearly the above example should work.

Klod

Posted on 2009-10-04 23:05:39 by Klod

As can be seen from the -e assembly Mov Bx, ddBlah(.High) assembled to  Mov Bx, ddBlah+HighLow.High, what I wanted but I get MacroTest.asm:25: error: COFF format does not support non-32-bit relocations


It is indeed working, but the operation is being treated as a non-32-bit relocation, something which COFF doesn't like.

Off-hand, I would have to say that it is because "Mov Bx, ddBlah(.High)" assembles to "Mov Bx, ddBlah+HighLow.High", where ddBlah is an offset/address to a variable in the data section and HighLow.High ends up being an offset/address to an absolute (different) section... perhaps making an impossibly complex relocation.

Are you sure you weren't intending to use %define ddBlah(x)  ?
Posted on 2009-10-05 01:43:22 by SpooK

Off-hand, I would have to say that it is because "Mov Bx, ddBlah(.High)" assembles to "Mov Bx, ddBlah+HighLow.High", where ddBlah is an offset/address to a variable in the data section and HighLow.High ends up being an offset/address to an absolute (different) section... perhaps making an impossibly complex relocation.


Over-thought that one last night... it is as simple as the fact that "Mov Bx, ddBlah..." is causing NASM to generate a 16-bit (2 byte) relocation entry.

The resultant solution still stands as correct, though.
Posted on 2009-10-05 09:31:44 by SpooK
Hi SooK
You were right in your assumption As soon as I read your first post it clicked. I cahnge the code to the example posted and it works. I wanted to leave the [] out of the macro so I could
Mov Ax, word
Mov edx, ddBlah(.High) ;get the address
Here is my working example:
EXTERN wsprintfA
EXTERN ExitProcess
EXTERN MsgBox

STRUC HighLow
.High RESW 1
.Low RESW 1
ENDSTRUC

SECTION .data

ddBlah DD 123456789
strFmt DB `High Word: %d\nLow Word: %d\nADDRESS ddBlah DWord: %d\n`, 0
buffer TIMES 1024 db 0
caption db 'Testing',0
SECTION .text

Global Start
Start:
xor eax,eax
xor ebx,ebx
%define ddBlah(x)  ddBlah+HighLow %+x
Mov Ax, word
Mov Bx, word ;This is what I wanted
Mov edx, ddBlah(.High) ;get the address
%undef ddBlah
push edx
Push Eax
Push Ebx
Push DWORD strFmt
push dword buffer
Call wsprintfA
push caption
push buffer
call MsgBox
push 0
call ExitProcess

;Radasm IDE 3,O,$B\NASM -Ox -fwin32 ,2
;5,O,$B\GOLINK @$B\GFL.txt /entry Start ,3,4

This compiles and runs, producing the right out put.

This proves that Nasm works as expected.
In Regards to Synfires assume macro I cannot make it work If I substitute the learned lesson from the previous example then the following works:

%imacro ASSUME 2
        %ifidni %2, NOTHING
                %undef %{1}.
        %else
                %define ddBlah(x)  ddBlah+HighLow %+x   
        %endif
%endm

ASSUME ddBlah, HighLow
Mov Ax,word
Mov Bx,word
ASSUME ddBlah, NOTHING


In this example all works as before. The problem starts if I replace
%define ddBlah(x)  ddBlah+HighLow %+x  ;this works
%idefine %{1}.(x) %{1} + %{2}. %+ x    ;error: parser: expecting ]

This is what I have tried to solve in the first place. Regardless on how I arrange the parameters it will not work I think its in the combining of more than two symbols that (x) gets appended as a "string" instead as a parameter.

All suggestions are welcome
Klod



Posted on 2009-10-07 00:43:38 by Klod
You aren't seeing what I was saying in the first place. you can't use:
%idefine %{1}.(x) %{1} + %{2}. %+ x


because nasm doesn't catenate it properly. That's the typo I was talking about. Look closely at my example above:

%idefine %{1}.(x) %{1} + %{2} %+ . %+ x


there is an extra %+ operation to push the calculation of the structure offset onto the second pass whereas the first version addresses %{2}. on the first pass then incorrectly attempts to fixup the resulting x. Basically we need to add the extra %+ to "confuse" NASM so it doesn't know what to do with it on the first pass and waits until it makes it's second pass through the source to attempt to generate the symbol we need. Also, I don't really find the -e option very useful in situations like this as we aren't wanting to see what the preprocessor generates, rather what the final pass is generating (hint hint to any dev team members out there for a possible new feature :p).
Posted on 2009-10-07 07:46:47 by Synfire
Hi Synfire
Thanks for replying. Still negative, I had tried that before already
%idefine %{1}.(x) %{1} + %{2} %+ . %+ x,  This produces error parser: expecting ]

The ] error seems to suport your explanationtough
Klod


Posted on 2009-10-07 09:57:48 by Klod
I'll get on a win-box this afternoon and work it out then. It's working here, I'm not sure whats wrong.
Posted on 2009-10-07 10:39:15 by Synfire
Okay, I've jumped onto this winbox and took my previous example and changed it slightly for Windows usage:

	BITS 32

%imacro ASSUME 2
        %ifidni %2, NOTHING
                %undef %{1}.
        %else
                %idefine %{1}.(_x_) %{1} + %{2} %+ . %+ _x_
        %endif
%endm

STRUC HighLow
.High RESW 1
.Low RESW 1
ENDSTRUC

SECTION .data

ddBlah DD 123456789
strFmt DB `High Word: %d\nLow Word: %d\nAddress of High Word: 0x%08X\nAddress of Low Word: 0x%08X`, 0
strBuf TIMES 1025 DB 0

SECTION .text

Global start
start:
Xor Eax, Eax
Xor Ebx, Ebx

ASSUME ddBlah, HighLow
Mov Ax,
Mov Bx,
Lea Edx,
Lea Ecx,
ASSUME ddBlah, NOTHING

Push Edx
Push Ecx
Push Eax
Push Ebx
Push DWORD strFmt
Push DWORD strBuf
Extern wsprintfA
Call wsprintfA
Add Esp, (3*4)

Push DWORD 0
Push DWORD 0
Push DWORD strBuf
Push DWORD 0
Extern _MessageBoxA@16
Call _MessageBoxA@16

Push DWORD 0
Extern _ExitProcess@4
Call _ExitProcess@4


However, the assume macro itself is unchanged as you can see above. This code worked fine. Built using 'nasm -f win32 test.asm' and linked with 'golink test.obj kernel32.dll user32.dll'. Looking closer at your code, the problem is in how you are trying to address the high-word of ddBlah. You need to use Lea like above.
Posted on 2009-10-07 15:01:51 by Synfire
%imacro ASSUME 2
        %ifidni %2, NOTHING
                %undef %{1}.
        %else
                %idefine %{1}.(_x_) %{1} + %{2} %+ . %+ _x_
                %warning %{1}.(_x_)
        %endif
%endm

Test.asm:32: (ASSUME:7) %warning: ddBlah + HighLow._x_
Test.asm:33: error: symbol `HighLow._x_' undefined
Test.asm:34: error: symbol `HighLow._x_' undefined
Test.asm:35: error: symbol `HighLow._x_' undefined
Test.asm:36: error: symbol `HighLow._x_' undefined

These are the errors I started out with.
You mentioned a better -e as being a poor debug tool but I do not know of a better one, except warnings
I have attached a zip file of your program with make file.You can try it on your xbox.

I thought I may have a problem with my machine. I have tried the program on two other machines, 1 XP pro and one XP home and the errors are the same.

Being stumped

Klod
Attachments:
Posted on 2009-10-07 23:11:33 by Klod
Sorry it's taken a while but I don't regularly have access to the Windows operating system. Running your Make.bat file I immediately noticed two problems; you used 'Start' instead of 'start' and you have defined test.obj twice in your Make.bat file's Linking option. This makes two instances of each symbol causing a failure to build. Also, I didn't say to use %warn as a debugging method over -e, I was just saying that -e doesn't really work in a manner in which would be most useful in diagnosing macros. Attached below is a repaired version of your attachment. I've built and ran it without errors.
Attachments:
Posted on 2009-10-10 00:05:41 by Synfire
Okay, okay, okay, I'll join your club... hadda do it to get the .zip file(s). :)

Hi SpooK, Hi Synfire, Hi Klod,

I know I said (elsewhere) that I was going to give this thread a rest, but... just a couple observations...

In Klod's version of the file, if I replace "%warning %{1}.(_x_)" (which shows "_x_") with "%warning %{1}.(Low)", I get the "intended" warning. Either way, the actual expansion of the macro seems to work (as shown by the "-e" switch... and by not getting any "undefined" errors).

However, if I replace "%idefine" (in the meat of Synfire's macro) with "%ixdefine", I get "symbol 'HighLow._x_' undefined" (4 times) - just like Klod is describing! So my advice (elsewhere) that "%xdefine" might help is 180 degrees wrong!

(all results under Linux, but assembling to "-f win32")

I don't know if any of that will help anybody figure out what's going wrong...

Best,
Frank

Posted on 2009-10-10 02:09:48 by fbkotler
Hi Frank,

First, welcome to the board. :)

Klods version assembled fine for me with the exception of duplicate errors which could be fixed by removing the 'test.obj' from the end of his golink definition. However I did receive a few linking errors regarding 'Start' as golink expects to see 'start' as the entry point unless explicitly defined on the command line. What I was commenting on the '-e' option is that, when checking the output it would be nice to be able to choose what pass gets dumped to the output. When I was testing this and tried the '-e' option it would display the macro itself instead of what the macro was translating into.

Mov Ax, 


instead of

Mov Ax, 


Which is what I was really trying to see, what it was translating into.

As far as I can tell, the attachment I posted has built and ran on Windows XP SP3, Windows 2000 Professional SP2 and it built (wouldn't link) under GNU/Linux. I tried to link it using golink and wine on Gnu/Linux but apparently golink doesn't like Wine's DLLs :)
Posted on 2009-10-10 04:18:12 by Synfire
First, thanks for having me!

I agree that it might be nice to have the "-e" switch dump the last (or next to last) pass instead of the first one. Forward references might come out better (Nasm really doesn't do forward references at all in "-e" mode...).

But I don't see what you mean about seeing "the macro itself". What I see is only the expansion of the macro... plus a bunch of "%line" macros (I don't know anything about 'em)... "nasm -f win32 test.asm -e > test.pre"

;; first we expand "bits 32" to its "raw" form (does nothing in "-f win32")
%line 1+1 test.asm


%line 13+1 test.asm

;; expansion of the "struc" macro

%line 14+0 test.asm
HighLow:
%line 15+1 test.asm
.High RESW 1
.Low RESW 1
HighLow_size equ ($-HighLow)
%line 17+0 test.asm

;; expansion of "section .text"

%line 18+1 test.asm

;; expansion of "section .data"


ddBlah DD 123456789
strFmt DB `High Word: %d\nLow Word: %d\nAddress of High Word: 0x%08X\nAddress of Low Word: 0x%08X`, 0
strBuf TIMES 1025 DB 0




Start:
Xor Eax, Eax
Xor Ebx, Ebx

;; the ASSUME macro doesn't show
;; but here's the expansion of its contents
Mov Ax,
Mov Bx,
Lea Edx,
Lea Ecx,
;; the "ASSUME nothing" macro is gone, too
;; this is the section that isn't working for Klod!

;; note "mov ecx ddBlah + HighLow.High" works too,
;; but "lea" is "safer" in that it'll handle "ddBlah" being on the stack

Push Edx
Push Ecx
Push Eax
Push Ebx
Push DWORD strFmt
Push DWORD strBuf

;; "extern"s a macro, too...

Call wsprintfA
Add Esp, (3*4)

Push DWORD 0
Push DWORD 0
Push DWORD strBuf
Push DWORD 0

Call _MessageBoxA@16

Push DWORD 0

Call _ExitProcess@4

Pretty much what I'd expect. I don't know why it isn't working for Klod. I suggested, in another forum, that different compilers sometimes produce slightly different code, but that's far-fetched (I hope). Maybe eight hours sleep and a bowl of Wheaties will fix it. :)

Best,
Frank

Posted on 2009-10-10 07:48:13 by fbkotler
hrm, okay this must have been an old issue... the remark came from a test build I did on windows, here is a copy of the results file:

%line 1+1 Test.Asm


%line 10+1 Test.Asm


%line 11+0 Test.Asm
HighLow:
%line 12+1 Test.Asm
.High RESW 1
.Low RESW 1
HighLow_size:
%line 14+0 Test.Asm

%line 15+1 Test.Asm



ddBlah DD 123456789
strFmt DB `High Word: %d\nLow Word: %d\nAddress of High Word: 0x%08X\nAddress of Low Word: 0x%08X`, 0
strBuf TIMES 1025 DB 0




start:
Xor Eax, Eax
Xor Ebx, Ebx


Mov Ax,
Mov Bx,
Lea Edx,
Lea Ecx,


Push Edx
Push Ecx
Push Eax
Push Ebx
Push DWORD strFmt
Push DWORD strBuf

Call wsprintfA
Add Esp, (3*4)

Push DWORD 0
Push DWORD 0
Push DWORD strBuf
Push DWORD 0

Call _MessageBoxA@16

Push DWORD 0

Call _ExitProcess@4


however, I know I hadn't used that computer in a while and pending your recent post I updated my copy and received the same output you got. In the older version it would expand the original macro but not the nested single-line macros (as seen above). I like it much better the way it is now. As for anything else I can continue using the -l option. :)
Posted on 2009-10-10 08:31:02 by Synfire
Hi Synfire, Hi Frank
With interest have I followed your postings. I was assuming that the the out put from the -e option would be from the last pass and not from any other. So I was convinced the whole time the problem was a preprocessor one.
I have to admit that I got a bit sloppy with my make file. I use Radasm and do not usually use make files.
you used 'Start' instead of 'start' and you have defined test.obj twice in your Make.bat

I also never used Global start but used /entry Start on the command line for golink.
I run the corrected version of the test program and it works as intended. I copied it to my usb stick (I have a copy of nasm and radasm on it, and tried it on my home computer and it fails with the same error codes as I had before. The version of Nasm on my usb stick was nasm-2.06rc10 which I had installed via installer. the version on my Laptop is nasm-2.07 which I manually installed from zip File. I changed the files on my usb stick to nasm-2.07 and it works like a charm.

Sanity has once again returned to me even if its for a short while

Thanks for all your help
Klod
Posted on 2009-10-10 20:56:53 by Klod

Okay, okay, okay, I'll join your club... hadda do it to get the .zip file(s). :)

Hi SpooK, Hi Synfire, Hi Klod,

I know I said (elsewhere) that I was going to give this thread a rest, but... just a couple observations...


Best,
Frank



Welcome to the board.
Thanks for all the help you have given me in the past.

Andy
Posted on 2009-10-11 08:07:28 by skywalker