I'm trying to write a Jump table Macro, kinda like the one bitRake wrote for Masm. I pretty much have it figured out, however I've run into a paticular problem with concatenations. Here it is stripped down

I was hoping the following macro
macro Tbl low,upr

{ repeat upr-low+1
dd .a#low+%
end repeat
}

When called as Tbl 1000,1001 would generate the following
dd .a1000

dd .a1001

Anyway the above macro comples fine, but strange thing happens, the jump labels its supposed to be generating mustn't be working properly.

When I actually type in the desired two lines everything works so this leads me assume I'm not doing the concatenations properly. I've read the pre doc but I can't figure it out. :(

EDIT- from playing around with it I think .a#low+% is producing .a1000 which is then converted to label value and then the % is added. Is there any solution to this though :confused:
Posted on 2002-08-26 13:07:41 by Eóin
This is because concatenations are made by preprocessor, and calculations (like foo+%) are made by assembler. With current fasm architecture it'd be hard to do it other way, because for fasm's preprocessor numbers are nothing but strings, the parser recognizes whether they are immediate numbers, reserved words or labels, and finally assembler calculates the operations.
I'm sorry, I don't see a solution for your problem right now. :(
Posted on 2002-08-26 13:31:08 by Tomasz Grysztar
Its ok, I can work around it, just a bit more typing thats all. :)
Posted on 2002-08-26 17:04:45 by Eóin
For what purpose did you need it?
Posted on 2002-08-27 02:28:04 by Tomasz Grysztar
Its for a jump table, I tend to mostly use them for processing WM_COMMAND message, but I've found plenty of other uses at times as well. Here it is,
macro JmpTbl reg,id,low,upr,[Comp]

{ common
local ..skpTbl,..Tbl
sub reg,low
cmp reg,upr-low
ja ..skpTbl
jmp pd[..Tbl+reg*4]
..Tbl:
forward
dd .a#Comp
common
..skpTbl:
}
And here's an example,
mov eax,[wParam]

JmpTbl eax,a,1000,1004,1000,1001,1002,1003,1004
xor eax,eax
jmp .finish

.a1000: invoke SendMessage,[hWnd],WM_CLOSE,0,0

mov eax,1
jmp .finish

.a1001: invoke Beep,3024,100

mov eax,1
jmp .finish

.a1002: invoke Beep,5024,100

mov eax,1
jmp .finish

.a1003: invoke Beep,7024,200

mov eax,1
jmp .finish

.a1004: invoke Beep,11024,100

mov eax,1
jmp .finish
Posted on 2002-08-27 04:12:23 by Eóin
I think this solution is better:


macro JmpTbl reg,id,[val]
{ forward
..min = val
..max = val
forward
if val < ..min
..min = val
else if val > ..max
..max = val
end if
common
local ..skip,..tbl
sub reg,..min
cmp reg,..max-..min
ja ..skip
jmp near [..tbl+reg*4]
label ..tbl dword
repeat ..max+1-..min
forward
if %-1 = val
dd id#val
end if
common
if ($-..tbl) < %*4
dd ..skip
end if
end repeat
..skip: }

JmpTbl eax,a,1000,1001,1002,1004

a1000:
a1001:
a1002:
a1004:

Will work also with - for example - WM_ constants instead of numbers.
Posted on 2002-08-27 04:40:37 by Tomasz Grysztar
Very complex, don't know how you come up with your macros so quickly but I do like it. :)

Now forgive me if this is in the docs, I have checked but I find reading pdfs off a screen is difficult. Is there an option in Fasm to output the results after all the macros have been processed, but before any labels or actual assembling has taken place?

I don't know if it would even be possible, I presume the preprocessor would be let do its job, then output the results before the assembler gets its hands on things.

I had to make a minor change,
   forward

if %-1 = val[COLOR=darkred]-..min[/COLOR]
dd id#val
end if
Posted on 2002-08-27 07:36:13 by Eóin
Well, I don't know what do you need exactly, if you want to see the preprocessed source, you can insert the following lines after the "call preprocessor" and before the "call parser" instruction in the fasm.asm file:


mov edx,_preprocessed
call create
mov edx,[source_start]
mov ecx,[code_start]
sub ecx,edx
call write
call close
jmp _parse
_preprocessed db 'preproce.dat',0
_parse:

Then every preprocessed source will be written into preproce.dat file, but it will be in the fasm's source format, you'll probably need to convert it into human-readable form. If this is what you need, I can give you more information about the format of preprocessed source (I have already described it in the fasmGuide doc, something I have sent to the fasm's mailing list one day, but I can't find it now :().
PS. Yes, it was my mistake in that macro, posted it to quickly.
Posted on 2002-08-27 10:01:28 by Tomasz Grysztar