flat assembler
Message board for the users of flat assembler.

Index > Macroinstructions > Modyfing array variable in compilation time

Author
Thread Post new topic Reply to topic
alorent



Joined: 05 Dec 2005
Posts: 201
alorent
Hi guys,

I have a non common issue that not sure how it can be addressed.

I have a variable which defines a list of pointers to functions:

Code:
pListFunctions dd 10 dup (0)    


I would like that a separate coder create his functions and they are added to "pListFunctions" in *compilation time*. So, in runtime, I just have to walk over "pListFunctions" and just call each function on the list.

I was thinking that a separate coder could define his function and he just use a macro (let's call it ADD_FUNCTION) which automatically adds the function pointer to "pListFunction" (but in compilation time!). Example:

Code:
Function1 proc 

    ....
    ret 

Function1 endp

ADD_FUNCTION Function1    


Would the above could be implemented in FASM?

Thanks!
Post 25 Apr 2010, 19:50
View user's profile Send private message Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4242
Location: 2018
edfed
i think it is.
macro support local variable, but supoprt global variables too.

then, define a global pointer(equate?) to your array
use the global pointer as an offset in the array
update the pointer.

in practice i don't know how to do.


maybe it would be easier to create a function ot do this, and not a macro.

and use a macro to call this fucntion

macro add_func func{
push func
call addfunc
}
call
Post 25 Apr 2010, 20:29
View user's profile Send private message Visit poster's website Reply with quote
Tyler



Joined: 19 Nov 2009
Posts: 1216
Location: NC, USA
Tyler
If only I could find a way to store the address, I attempted to store the pointer with the last line but I get a weird error, "Error: code cannot be generated."
Code:
if ~functions_added = 0
   pListFunctions rd functions_added
end if
macro add_func addr
{
   if ~functions_added = 0
      functions_added = functions_added + 1
   else
      functions_added = 1
   end if
   store dword addr at (pListFunctions + (functions_added - 1) * 4)
}   
    
Post 25 Apr 2010, 21:08
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
Tyler, take a look at this:
Code:

   pListFunctions rd functions_added_final
   functions_added = 0

macro add_func addr
{
   functions_added = functions_added + 1
   store dword addr at (pListFunctions + (functions_added - 1) * 4)
}

alpha:ret
beta:ret
gamma:rep ret
epsilon:ret

add_func alpha
add_func gamma
add_func epsilon

functions_added_final = functions_added    
Post 25 Apr 2010, 21:34
View user's profile Send private message Reply with quote
Tyler



Joined: 19 Nov 2009
Posts: 1216
Location: NC, USA
Tyler
Loco: Nice, I was trying to keep everything self contained so that the variables were only processed if the macro was used, which complicated mine a little complicated. I still don't see where I screwed up.

I think this works, not so sure how to test it though. It assemblers w/o an error.
Code:
if defined functions_added
   pListFunctions rd functions_added
end if
macro add_func addr
{
   if ~(defined functions_added)
      functions_added = functions_added + 1
   else
      functions_added = 1
   end if
   store dword addr at (pListFunctions + (functions_added - 1) * 4)
}  
    
Post 25 Apr 2010, 21:50
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
invoke add_func twice or more and you'll get an out of scope error. I'm not sure what was causing the "code cannot be generated" error in your earlier version, I was expecting something like the error you get now with multiple invocations of add_func.
Post 25 Apr 2010, 21:56
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr
alorent,

Would comma-separated list of labels suffice? You may use something like
Code:
macro append name, [value] {
common
  match old_value, name \{
    restore name
    name equ old_value, value
  \}
  match , name \{ ; list is empty, no separator necessary
    restore name
    name equ value
  \}
}    
Usage is simple:
Code:
labels_list equ
...
append labels_list, Function1, Function2; and so on; 10 dup FunctionX is also valid Wink
...
pListFunctions dd labels_list    
Post 25 Apr 2010, 22:42
View user's profile Send private message Reply with quote
alorent



Joined: 05 Dec 2005
Posts: 201
alorent
Hello guys,

Thanks a lot for your help.

Tyler, Loco: 1st of all, THANKS! I have tried your solutions, but when I write:

add_func MyProc

I get a compiler error "value out of range"

Not sure if I have to call it in a different way.


baldr: Thanks for giving another solution. Unfortunatelly, I cannot use that approach. The functions must be added independently (from different modules) and not setting up the whole list at once.

Thanks!
Post 26 Apr 2010, 10:42
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr
alorent,

That macro doesn't build list at once, it appends its arguments to list and can be invoked multiple times. Like any other preprocessor solution, the resulting list can be used only after the last append macro invocation.

LocoDelAssembly's solution works OK for me. Note that exact order is important: functions_added = 0 should be before first add_func invocation, functions_added_final = functions_added should be after last (included files can mess with that).
Post 26 Apr 2010, 14:49
View user's profile Send private message Reply with quote
alorent



Joined: 05 Dec 2005
Posts: 201
alorent
Hello baldr,

Thanks for the information. Sorry, I thought that your solution created the list at once.

I have tried to use your solution but I think that I'm not doing it in the correct way:

Code:
include 'win32ax.inc' ; you can simply switch between win32ax, win32wx, win64ax and win64wx here
include 'macro\if.inc' 
include 'macro\masm.inc'

macro append name, [value] {
common 
  match old_value, name \{ 
    restore name 
    name equ old_value, value 
  \} 
  match , name \{ ; list is empty, no separator necessary 
    restore name 
    name equ value 
  \} 
}

.data 

labels_list:
dd 10 dup (0)


pListFunctions dd labels_list


.code 

start: 


append labels_list, MyProc
append labels_list, MyProc2

int 3
mov  eax, pListFunctions


MyProc proc

 ret

MyProc endp

MyProc2 proc

 ret

MyProc2 endp

.end start 
    



The resulting list is empty. Any ideas?

Thanks!
Post 26 Apr 2010, 17:27
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr
alorent,

You got it all the way wrong. Wink
Code:
include 'win32ax.inc' ; you can simply switch between win32ax, win32wx, win64ax and win64wx here
include 'macro\if.inc' 
include 'macro\masm.inc'

macro append name, [value] {
common 
  match old_value, name \{ 
    restore name 
    name equ old_value, value 
  \} 
  match , name \{ ; list is empty, no separator necessary 
    restore name 
    name equ value 
  \} 
}
labels_list equ

append labels_list, MyProc
append labels_list, MyProc2

.data

pListFunctions dd labels_list

.code

start: 


int 3
mov  eax, pListFunctions


MyProc proc

 ret

MyProc endp

MyProc2 proc

 ret

MyProc2 endp

.end start    
append invocations can be anywhere between labels_list equ and pListFunctions dd labels_list but the order is important.
Post 27 Apr 2010, 05:37
View user's profile Send private message Reply with quote
alorent



Joined: 05 Dec 2005
Posts: 201
alorent
Thanks baldr!

Will that approach work on multiple asm files (linked as OBJ files) on a single list? That is, each module call its own "append" macros? Finally, one module (asm) will be the one that reads the whole list and process it.

Thanks!!
Post 27 Apr 2010, 13:11
View user's profile Send private message Reply with quote
Tyler



Joined: 19 Nov 2009
Posts: 1216
Location: NC, USA
Tyler
No, you asked for something that affected code at compile time. Macros are processed before even the object code would be made.

You could do it at runtime, but I don't know of how to do such a thing with a linker because I don't use one. If you were to "link" the files by preprocessor-including them, it would work fine.
Post 28 Apr 2010, 03:02
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr
alorent,

"Modyfing array variable in compilation time", heh?

Well, even at link stage it is possible: linker merges similar (up to "$something" name suffix) sections.
Code:
; This is the main source
format MS COFF
section ".text" executable
        public  start
start:
        mov     eax, pListFunctions
        mov     ecx, pListFunctionsEnd
        ret

section ".data$a" readable
pListFunctions:

section ".data$c" readable
pListFunctionsEnd:    
Code:
; This is the first function
format MS COFF
section ".text" executable
Function1:
        mov     eax, 1
        ret

section ".data$b" readable
        dd      Function1    
Code:
; This is the second function
format MS COFF
section ".text" executable
Function2:
        mov     eax, 2
        ret

section ".data$b" readable
        dd      Function2    
Those section / dd sequences are the equivalent of add_func macro (and can be made such). Alas, pListFunctionsEnd-pListFunctions can't be computed at compile time, much less (pListFunctionsEnd-pListFunctions)/4 (can any linker perform simple computations with relocations?). Macro can count them.
Post 28 Apr 2010, 07:39
View user's profile Send private message Reply with quote
alorent



Joined: 05 Dec 2005
Posts: 201
alorent
Thanks baldr!!! Very Happy That's another approach! Wink
Post 29 Apr 2010, 07:11
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.

Website powered by rwasa.