Greetings,
here's a macro for defining an array of strings.
I've attached a simple console program to demonstrate it's use.
assemble and link it as a console program...
it demonstrates the use of $ :the location counter



STRINGARR macro varname:req,stringlist:vararg
;;written by Martial_Code 2003
;;defines an array of strings
;;varname : name of array which will receive the string offsets
;;stringlist: comma separated list of quoted strings,(use text equates to over come line length limitation)
;;eg: STRINGARR SIMPSONS,"La Famille Simpson","Homer","Marge","Bart","Lisa","Maggie","Santa's Little Helper","The Cat"
;;the array of offsets is call simpsons
;;this macro also generates a jmp to skip the data if defined in the code section
LOCAL lbl
IFNB <stringlist>
dwsize equ 4
len=0
i=0
datasize=0
sumdiff=0
%FOR arg,<stringlist>
i=i+1 ;get number of string elements
len SizeStr <arg>
len=len-1
datasize=datasize+len ;get the cumulative size of the text data
ENDM
j=0
%j INSTR <@CurSeg>,<_TEXT>
if j
jmp lbl
endif
j=0
%FOR arg,<stringlist>
local start ;start is defined here so that each time thru the loop it get a different value
len SizeStr <arg>
len=len-1 ;get number of bytes in the string includeing null char
start db arg,0 ;define data here
sumdiff=sumdiff+dwsize-len ;accumulative sum of misfit
ORG $+datasize-dwsize+sumdiff ;set location counter to next free slot in array of pointers
i=i-1
if j eq 0
@CatStr(<varname dword offset start>) ;only first time thru the loop defines varname
j=1
else
@CatStr(<dword offset start>) ;other times
endif
if i gt 0
ORG $-datasize-sumdiff ;set location counter to next free string offset only if more date to be defined
endif
ENDM
%j instr <@CurSeg>,<_TEXT>
if j
lbl:
endif
ENDIF
ENDM

*******EDIT**********
slight modification to macro:
it now allows text equates which can be used to overcome masm's 255 char line limit. see updated attachment on useage.
Posted on 2003-01-16 21:59:00 by MArtial_Code
Very nice work. Im glad you took the time to use the $ operator instead of sizing the array rectangularly (ie. making each entry the size of the longest array entry).

Once might argue the pointer table is wasteful, but verses the above rectangular approach this might as well be seen as encrytiping the added white spaces ;) . A pointer table entry is only 4 bytes, which is not much compared to an array like:

"Yes" (3 chars + Null)
"No" (2 chars + Null)
"Kinda sorta, im not sure" (24 chars + Null)

Rectangularly it would be 3*25 == 75 bytes for the array

Your macro will produce only 4+3+25+(4*3)=32+12= 44 bytes!

The tradeoff happens when your array items are very close to the same size. In this rare condition then the rectangular would be better. (But this rarely is the case with text strings ;) )

On an application sizde, this tool will be great for filling combo/drop boxes with intial data ;)

Thanx for the hard work.. This one is a keeper in my books..
As well, as MACROS can be a pain, i should say its also well written...
:alright:
NaN
Posted on 2003-01-16 22:44:52 by NaN
As a suggestion you should add an align statment:
STRINGARR macro varname:req,stringlist:vararg

;;written by Martial_Code 2003
;;defines an array of strings
;;varname : name of array which will receive the string offsets
;;stringlist: comma separated list of quoted strings
;;eg: STRINGARR SIMPSONS,"La Famille Simpson","Homer","Marge","Bart","Lisa","Maggie","Santa's Little Helper","The Cat"
;;the array of offsets is call simpsons
;;this macro also generates a jmp to skip the data if defined in the code section
LOCAL lbl
IFNB <stringlist>
dwsize equ 4
len=0
i=0
datasize=0
sumdiff=0
FOR arg,<stringlist>
i=i+1 ;get number of string elements
len SizeStr <arg>
len=len-1
datasize=datasize+len ;get the cumulative size of the text data
ENDM
j=0
%j INSTR <@CurSeg>,<_TEXT>
if j
jmp lbl
endif
j=0
FOR arg,<stringlist>
local start ;start is defined here so that each time thru the loop it get a different value
len SizeStr <arg>
len=len-1 ;get number of bytes in the string includeing null char
[COLOR=red]ALIGN 4[/COLOR]
start db arg,0 ;define data here
sumdiff=sumdiff+dwsize-len ;accumulative sum of misfit
ORG $+datasize-dwsize+sumdiff ;set location counter to next free slot in array of pointers
i=i-1
if j eq 0
[COLOR=red]ALIGN 4[/COLOR]
@CatStr(<varname dword offset start> ) ;only first time thru the loop defines varname
j=1
else
@CatStr(<dword offset start> ) ;other times
endif
if i gt 0
ORG $-datasize-sumdiff ;set location counter to next free string offset only if more date to be defined
endif
ENDM
%j instr <@CurSeg>,<_TEXT>
if j
lbl:
endif
ENDIF
ENDM


This makes the pipelines happy for when your char array's finish up on an odd number ;)

:NaN:
Posted on 2003-01-16 22:50:42 by NaN
Cheers nan...it was tough going trying to figure out the general formula for setting the location counter, I finally had to resort to the old gridded-paper and pencil "trick";) .

I've tried the align statements, placing align 4 before the text is decalred(first position in your post above), causes an error in the execuable. Aligning the the pointer array however seems to work fine. I'll have to look into it:confused: .
Posted on 2003-01-17 04:17:20 by MArtial_Code
Hmm.. thats strange.. i didnt test it, but it should have worked...

The quick fix migh just be @CatStr( <ALIGN 4> ).... :this is odd:

:NaN:
Posted on 2003-01-17 10:21:42 by NaN