I have on and off been looking for a method of duplicating the "typedef enum" data structures in C as it would make a number of extra structures available.
I found a posting by Ultrano from 2007 that has a useful if undocumented technique for MASM where you can use a structure to hold sequential values. Now the test piece below show the experiments done with this technique but as it has been many years since I used an "enum" data structure, I wonder if the method used in the example below is of any real use. If you load the structure members without allocating a structure in either the .DATA section or as a LOCAL variable, the order is treated like a sequence of constants if the structure uses BYTE sized members.
This is the test piece.
IF 0 ; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
Build this template with "CONSOLE ASSEMBLE AND LINK"
ENDIF ; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
include \masm32\include\masm32rt.inc
ENUM TEXTEQU <STRUCT>
BIDI_TYPE ENUM
BIDI_NULL db ? ; = 0
BIDI_INT db ? ; = 1
BIDI_FLOAT db ? ; = 2
BIDI_BOOL db ? ; = 3
BIDI_STRING db ? ; = 4
BIDI_TEXT db ? ; = 5
BIDI_ENUM db ? ; = 6
BIDI_BLOB db ? ; = 7
BIDI_TYPE ENDS
MYSTRUCT STRUCT
bidi BIDI_TYPE <>
var1 dd ?
var2 dd ?
MYSTRUCT ENDS
.code
start:
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
call main
inkey
exit
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
main proc
LOCAL mstr :MYSTRUCT
mov mstr.var1, 1234
print ustr$(mstr.var1),13,10,13,10
mov mstr.bidi.BIDI_NULL, MYSTRUCT.bidi.BIDI_NULL ; copy constant to memory
movzx eax, BYTE PTR mstr.bidi.BIDI_NULL
print ustr$(eax),13,10,13,10
print ustr$(MYSTRUCT.bidi.BIDI_TEXT),13,10,13,10
print ustr$(BIDI_TYPE.BIDI_NULL),13,10
print ustr$(BIDI_TYPE.BIDI_INT),13,10
print ustr$(BIDI_TYPE.BIDI_FLOAT),13,10
print ustr$(BIDI_TYPE.BIDI_BOOL),13,10
print ustr$(BIDI_TYPE.BIDI_STRING),13,10
print ustr$(BIDI_TYPE.BIDI_TEXT),13,10
print ustr$(BIDI_TYPE.BIDI_ENUM),13,10
print ustr$(BIDI_TYPE.BIDI_BLOB),13,10
ret
main endp
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
end start
my understanding of enumerations is that they are like having a structure of EQUates
defining them as data bytes (or words or dwords) doesn't seem to quite fill the bill
and, it takes up data space :P
at any rate, they are often parameters in INVOKE, so DB isn't good without first expanding them
If you look at the line of code,
mov mstr.bidi.BIDI_NULL, MYSTRUCT.bidi.BIDI_NULL ; copy constant to memory
You will see that its not the case. "mstr.bidi.BIDI_NULL" is a memory operand where the direct structure reference "MYSTRUCT.bidi.BIDI_NULL" functions as an immediate.
Yes, the enumeration (http://msdn.microsoft.com/en-us/library/8h84wky1(v=VS.80).aspx) functionality does not depend on there being any data allocated.
include \masm32\include\masm32rt.inc
ENUM STRUCT
_NULL db ? ; = 0
_INT db ? ; = 1
_FLOAT db ? ; = 2
_BOOL db ? ; = 3
_STRING db ? ; = 4
_TEXT db ? ; = 5
_ENUM db ? ; = 6
_BLOB db ? ; = 7
ENUM ENDS
.code
start:
print ustr$(ENUM._NULL),13,10
print ustr$(ENUM._INT),13,10
print ustr$(ENUM._FLOAT),13,10
print ustr$(ENUM._BOOL),13,10
print ustr$(ENUM._STRING),13,10
print ustr$(ENUM._TEXT),13,10
print ustr$(ENUM._ENUM),13,10
print ustr$(ENUM._BLOB),13,10
inkey
exit
end start
But this still seems like a clumsy way to do it. Is there some other benefit to having the structure definition that I'm just not seeing?
I am trying to get them going because of the number of structures that include a "typedef enum" member.
The unallocated ENUM clearly works as a constant.
LOCAL mstr :MYSTRUCT
mov al, MYSTRUCT.bidi.BIDI_BLOB
movzx ecx, al
print ustr$(ecx)," written to a BYTE sized register",13,10
mov ax, MYSTRUCT.bidi.BIDI_BLOB
movzx ecx, ax
print ustr$(ecx)," written to a WORD sized register",13,10
mov ecx, MYSTRUCT.bidi.BIDI_BLOB
print ustr$(ecx)," written to a DWORD sized register",13,10,13,10
mov mstr.bidi.BIDI_NULL, MYSTRUCT.bidi.BIDI_NULL ; copy constant to memory
movzx eax, BYTE PTR mstr.bidi.BIDI_NULL
print ustr$(eax),13,10,13,10
print ustr$(MYSTRUCT.bidi.BIDI_TEXT),13,10,13,10