I have a MACRO problem, that i think can not be solved, but I thought i would post it to test the limitless knowledge of this community ;)

If at compile time, a macro "A" builds a table of data at a label in the .data segment:

A_Macro_Output LABLE DWORD
dd 0
dd 1
dd 3

As well, this same macro stores the size:

A_Macro_Output_Size equ 12


Can another compile time macro copy the 12 data bytes at compile time to another area in the .data segment further on in the source compilation??

B_Macro_Copy A_Macro_Output, A_Macro_Output_Size

And generate a new table:

B_Macro_Output LABEL DWORD
dd 0
dd 1
dd 3

This is a tough conundrum. In theory it should be able to, since the first macro has immediate data to compile, it thus means the latter macro should find immediate data at the label location in the segment. However, on the flip side, i dont know how M$ made MASM, and it may not linerally build the .data segment (as im assuming), and place the .data immediate values on another compiler pass through the source.

Anywho, if you think you can crack this problem, please let me know!
Thanks alot!
:NaN:
Posted on 2003-07-14 19:41:25 by NaN
This is the best i can come up with (names are arbitrary):
QC MACRO LA:REQ, DA:REQ

.data
LA LABEL DWORD
dd DA
dd DA + 1
dd DA + 2
ENDM


QCC MACRO LA:REQ, LB:REQ
.data
LA LABEL DWORD
dd DWORD PTR [LB + 0]
dd DWORD PTR [LB + 4]
dd DWORD PTR [LB + 8]

ENDM


With test code:
QC ABCD, 5


PrintHex ABCD+0, "TEST"
PrintHex ABCD+4, "TEST"
PrintHex ABCD+8, "TEST"

QCC EFG, ABCD

PrintHex EFG+0, "TEST"
PrintHex EFG+4, "TEST"
PrintHex EFG+8, "TEST"

Produces this output:
ABCD+0 = 00000005, TEST

ABCD+4 = 00000006, TEST
ABCD+8 = 00000007, TEST
EFG+0 = 00403060, TEST
EFG+4 = 00403064, TEST
EFG+8 = 00403068, TEST


Turns out that it places a pointer, to *where* to copy from, instead of the data itself. Despite my best efforst to tell it to get the data. ((00403060h points to a dword in memory initialized to "00000005"))

:NaN:
Posted on 2003-07-14 20:05:38 by NaN
Hi NaN

Why not coding:



QC MACRO LA:REQ, DA:REQ
.data
LA LABEL DWORD
LA&0 equ DA
LA&1 equ DA + 1
LA&2 equ DA + 2
dd LA&0
dd LA&1
dd LA&2
ENDM


QCC MACRO LA:REQ, LB:REQ
.data
LA LABEL DWORD
dd LB&0
dd LB&1
dd LB&2

ENDM


?
Posted on 2003-07-14 21:19:30 by japheth
Nan,
No problem, I do this sort of thing all the time. The trick is to use specific global variables. Specific in the sense that they will not be confused with the global variables of another macro, and global in that they can be referenced anywhere in the assembly. I make them specific by including the macro name as part of the global variable name. See example below. Ratch



= OFFSET @ EQU OFFSET

QC MACRO LA:REQ,DA:REQ ;define macro

QC$1=DA ;load global variable
QC$2=DA+1 ;load global variable
QC$3=DA+2 ;load global variable
;
LA LABEL DWORD
DD DA
DD DA+1
DD DA+2
ENDM

QCC MACRO LA:REQ ;define macro
LA LABEL DWORD
DD QC$1 ;reference global variable
DD QC$2 ;reference global variable
DD QC$3 ;reference global variable
ENDM

00000000 .DATA?

00000000 .DATA
00000000 00000009 DD 9
00000004 0000000A DD 10

QC ABCD,4 ;call the macro
1
= 00000004 1 QC$1=4 ;load global variable
= 00000005 1 QC$2=4+1 ;load global variable
= 00000006 1 QC$3=4+2 ;load global variable
1 ;
00000008 1 ABCD LABEL DWORD
00000008 00000004 1 DD 4
0000000C 00000005 1 DD 4+1
00000010 00000006 1 DD 4+2

00000014 8B C1 MOV EAX,ECX
00000016 90 NOP
00000017 83 C1 04 ADD ECX,4

QCC EFG ;call the macro
0000001A 1 EFG LABEL DWORD
0000001A 00000004 1 DD QC$1 ;reference global variable
0000001E 00000005 1 DD QC$2 ;reference global variable
00000022 00000006 1 DD QC$3 ;reference global variable
00000000 .CODE
.LISTALL

00000000 START:
00000000 B8 00000008 R MOV EAX,@ ABCD ;address of label
00000005 A1 00000008 R MOV EAX,[ABCD] ;contents of label
0000000A B8 0000001A R MOV EAX,@ EFG ;address of label
0000000F A1 0000001A R MOV EAX,[EFG] ;contents of label

END START
Posted on 2003-07-14 21:27:51 by Ratch
NaN, I don't really understand your requirements, but in the extreme case you could even create the array of data in assemble-time constants and then create a macro to build the array where ever.

What is stated in the first post is impossible - MASM cannot copy arbitrary data from one part of the .data segment to another. So, the key now becomes duplicating the table creation method in another location. If Ratch's method is sufficient then it is the way to go. {japheth's code is basically the same.}
Posted on 2003-07-14 22:25:58 by bitRAKE
Thanks both of you for your suggestion (im actually doing the same thing myself at the moment).

However, im still reluctant. I dont like having to add all those equates (One per line of memory i want to copy). I was hoping for a more logic driven solution.

The reason is cause im almost finished my next version of my OOP model. And for polymorphic action, i need to copy existing vtables into a new one for classes that are to be used polymorphicly. So to allow for *any* class vtable to be copied, i would have to make an extra equate for every method, to hold a copy at compile time of function offsets. All this just for the chance the equate may be called upon for a polymorphic class that inherits another vtable's methods as a base class.

It works, just not the prettiest solution. ((I want to make an honest attempt at limiting how much compiler overhead is required to process the objects ))

Thanx again! It is appreciated!
:alright:
NaN
Posted on 2003-07-14 22:33:53 by NaN
While i got everyone's attention, I have another, simpler macro question.

I dont ever to MACRO for or while loops. I know they unroll at compile time, but thats about it. Im about to hit the reference manual my self to "relearn" them, but i thought i would toss out what i need to do at the same time ;)

I have in an equate the number of bytes that need to be "copied". Since difference classes will have different lengths, this value is a random multiple of 4bytes (dword pointers).

I want to make a macro for loop that will loop like the C++ version:

for ( new_equ = 0; new_equ < equ_sized; new_equ += 4)
{
...
}

And have it unroll with new_equ holding 0, 4, 8, etc. depending on the value of the sized equate.

If you can help here, thanx in advanced!
:NaN:
Posted on 2003-07-14 22:41:31 by NaN
Heh, nevermind, that was easier than i thought it would be ;)

Found the solution in an old macro i wrote for Unicode (while loops)

http://www.asmcommunity.net/board/index.php?topic=9273

:alright:
NaN
Posted on 2003-07-14 22:50:31 by NaN
If I understood correctly, you were trying to set two "blocks" of variables in the .data section, with the same size, and initialized with the same values. Both "blocks" are defined using macros. So why not using a single macro, and the ORG directive to place them wherever you want? I'm not familiar with the use of ORG under MASM, but I remember you could do something like that in the old A86 for DOS (by the way, I don't know much of the macro languaje in MASM yet, but it seems to me that A86 was far better in some aspects, don you think? :) )
Posted on 2003-07-15 09:31:42 by QvasiModo
I never used A86. But i do have clear reasons for two separate macro's. Like i said earlier, im working on a next generation OOP model. Its now finished, and i got a working solution (as Japheth & Ratch pointed out). Again the reason I need to copy is since some class instances may be "Lines" and others "Squares", where squares utilize all of the data/methods that Line has, and extends it further to act as a square class. So I need two "finger prints" of line, one for each class, and add more to the square above and beyond its copy.

Sorry if this confuses you, its as simple as I can put it...
:alright:
NaN
Posted on 2003-07-15 11:44:33 by NaN
Don't worry NaN, you haven't been confusing, it's just I don't know anything about OOP :grin:
Posted on 2003-07-15 16:33:51 by QvasiModo

Thanks both of you for your suggestion (im actually doing the same thing myself at the moment).

However, im still reluctant. I dont like having to add all those equates (One per line of memory i want to copy). I was hoping for a more logic driven solution.

The reason is cause im almost finished my next version of my OOP model. And for polymorphic action, i need to copy existing vtables into a new one for classes that are to be used polymorphicly. So to allow for *any* class vtable to be copied, i would have to make an extra equate for every method, to hold a copy at compile time of function offsets. All this just for the chance the equate may be called upon for a polymorphic class that inherits another vtable's methods as a base class.

It works, just not the prettiest solution. ((I want to make an honest attempt at limiting how much compiler overhead is required to process the objects ))

Thanx again! It is appreciated!
:alright:
NaN


You're encountering many of the same problems I had when using MASM back in 1995/6 that drove me to design and implement HLA!

Seriously, though, the best I was able to do with respect to maintaining "compile-time" variables, particularly arrays, in ASM to to create a string of values separated by some delimiter (e.g., ":" ) and then pick apart those objects later on. For some of the craziness I wound up creating in MASM, check out
http://webster.cs.ucr.edu/Page_asm/ucrlib/stdlibv2.html

I'll warn you that many of the macros I wrote wound up breaking as Microsoft moved from MASM v6.11a to v6.11d; that's when I gave up and started work on HLA.

You will find some interesting macros in this package, though. For example, I implemented a try..except..endtry macro sequence (fully nestable) using the trick I mentioned above (I used a string to hold a "stack" of data to remember the nesting level in the "try" statement).

If you ever find that MASM's macro facilities don't cut it for your object implementation, you might take a look at HLA - it already has classes built into it and handles VMT generation automatically (well, mostly, you still have to tell HLA *where* to put the VMT for a given class).
Cheers,
Randy Hyde
Posted on 2003-07-17 11:47:26 by rhyde
Hell over there!

What can I do, to use labels in a macro.
I want to use the macro several times, but it's not possoble, cuz than there a labels wich are the same.

Do someone have a glory idea ?
Posted on 2003-07-22 05:55:48 by Bubu-Boy
How about defining your labels as locals?


SAMPLE macro
local MyLabel

; put some stuff here
MyLabel:
;some more stuff here
jmp MyLabel
;well, you get the picture ;)
endm

I never tried (I'm new to macro programming too :) ), but it should work...
Posted on 2003-07-22 11:21:19 by QvasiModo
hI!

This works with MASM, if assembler does two cicles.

;; ** FOR ******************************** MACRO DE CONTROL ESTRUCTURADO **
;; Macro FOR estructurada. Util?cese as?:
;; FOR contador,inicio,final,signo
;;
fork MACRO p1,p2,p3,p4,p5
LOCAL primero
LOCAL ifcierto
IFNDEF ?for_nivel ;; establece nuevo nivel de anidado
?for_nivel = 10
ELSE
?for_nivel = ?for_nivel + 1
ENDIF
;; Establece nuevo n?mero de secuencia para nivel de anidado
testsim ?for_anid,%?for_nivel
IF (?simdef)
incrsim ?for_anid,%?for_nivel
ELSE
cerosim ?for_anid,%?for_nivel
ENDIF
;; Inserta inicializaci?n de contador en el c?digo: (evitando paso 1)
mov &p1,&p2 ; Inicializa contador
jmp primero ; Comienza bucle FOR
;; Inserta etiqueta inicio bucle para salto
etsalto ?for_,%?for_nivel,?for_anid
;; Inserta c_lculo paso en c?digo, y comprueba que el paso es correcto
IFIDN <p4>,<+>
add &p1,&p5 ; Incremento de contador
ELSE
IFIDN <p4>,<->
sub &p1,&p5 ; Decremento de contador
ELSE
; ERROR: especificaci?n de paso incorrecta para sentencia FOR
EXITM
ENDIF
ENDIF
primero: ; Comprueba la continuaci?n
;; Inserta en el c?digo la comprobaci?n de condici?n
cmp &p1,&p3 ; ?Se alcanz? el final?
;; Salto a la secci?n de c?digo de FOR: CIERTO
IFIDN <p4>,<+>
jl ifcierto ; No: contin?a en el bucle FOR
ELSE ;; caso '-' (por defecto)
jg ifcierto ; No: contin?a en el bucle FOR
ENDIF
;; Pasa a la etiqueta siguiente
incrsim ?for_anid,%?for_nivel
;; Inserta, en c?digo, salto al final del bucle
salto ?for_,%?for_nivel,?for_anid
ifcierto:
ENDM
;; ** FOREND ******************************** MACRO DE CONTROL ESTRUCTURADO **
;; Macro FOR_END estructurada para combinar con FOR
;; FOREND genera el c?digo de un bucle FOR estructurado
forend MACRO
IFNDEF ?for_nivel
; ERROR: FOREND sin sentencia FOR
EXITM
ENDIF
IF (?for_nivel LT 10)
; ERROR: FOREND sin sentencia FOR
EXITM
ENDIF
;; Vuelta a la etiqueta anterior de la secuencia
decrsim ?for_anid,%?for_nivel
;; Genera salto al comienzo del bucle
salto ?for_,%?for_nivel,?for_anid
;; Pasa a la siguiente etiqueta de la secuencia
incrsim ?for_anid,%?for_nivel
;; Genera etiqueta FOREND
etsalto ?for_,%?for_nivel,?for_anid
?for_nivel = ?for_nivel - 1
ENDM
Posted on 2003-07-22 11:47:54 by miguelossa
Sorry, the macro above doesn't work without other dependencies.

I attach all the file. You'll see that incloses another macros.

Please, I didn't test these macros with masm32. Coult you tell me if they can compile?

Thanks
:alright:
Posted on 2003-07-22 12:07:13 by miguelossa