News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Enum macro for MASM???

Started by ThoughtCriminal, April 14, 2007, 07:51:16 AM

Previous topic - Next topic

ThoughtCriminal

I like to code for small code, so I maek an enum like this:

o0 = 0
ExitProcess = o0+0
GetCommandLine = o0+4
GetLastError = o0+8
GetModuleHandle = o0+12
o1 = o0+(4*4)
Direct3DCreate9 = o1+0
.D3D = o1+0
o2 = o1+(1*4)
CreateWindow = o2+0
RegisterClass = o2+4
ShowWindow = o2+8
UpdateWindow = o2+12
GetMessage = o2+16
TranslateMessage = o2+20
DispatchMessage = o2+24
PostQuitMessage = o2+28
DefWindowProc = o2+32
LoadIcon = o2+36
LoadCursor = o2+40
o3 = o2+(11*4)
LoadApi = o3+0

Then I can shorten  most calls to 3 byte insteed of 5 or 6:  As long as I keep the range  in -7fh to 7fh.

mov ebp,offset FUNC0   ;use ebp as a pointer to my enum table
mov edi,offset DATA0    uuse edi  as a pointer to my data table

eMSG = eWINC+(-7*4)
hwnd = oMSG-28
message = oMSG-24
wParam = oMSG-20
lParam = oMSG-16
time = oMSG-12
x = oMSG-8
y = oMSG-4
oMSG = -52;oWINC-(12*4)
eWINC = -48
cdSize = oWINC-48
style = oWINC-44
lpfnWndProc = oWINC-40
cbClsExtra = oWINC-36
cbWbdExtra = oWINC-32
hInstance = oWINC-28
hIcon = oWINC-24
hCursor = oWINC-20
hbrBackground = oWINC-16
lpszMenuName = oWINC-12
lpszClassName = oWINC-8
hIconSm = oWINC-4
oWINC = 0

eMSG = eWINC+(-7*4)
hwnd = oMSG-28
message = oMSG-24
wParam = oMSG-20
lParam = oMSG-16
time = oMSG-12
x = oMSG-8
y = oMSG-4
oMSG = -52;oWINC-(12*4)
eWINC = -48
cdSize = oWINC-48
style = oWINC-44
lpfnWndProc = oWINC-40
cbClsExtra = oWINC-36
cbWbdExtra = oWINC-32
hInstance = oWINC-28
hIcon = oWINC-24
hCursor = oWINC-20
hbrBackground = oWINC-16
lpszMenuName = oWINC-12
lpszClassName = oWINC-8
hIconSm = oWINC-4
oWINC = 0

invoke FP@48 ptr[ebx]+CreateWindow,esi,eax,[edi][WinClass.lpszClassName],00CF0000h,ecx,ecx,ecx,ecx,esi,esi,[edi][WinClass.hInstance],esi
00401096 56               push        esi 
00401097 FF 77 14         push        dword ptr [edi+14h]
0040109A 56               push        esi 
0040109B 56               push        esi 
0040109C 51               push        ecx 
0040109D 51               push        ecx 
0040109E 51               push        ecx 
0040109F 51               push        ecx 
004010A0 68 00 00 CF 00   push        0CF0000h
004010A5 FF 77 28         push        dword ptr [edi+28h]
004010A8 50               push        eax 
004010A9 56               push        esi 
004010AA FF 53 14         call        dword ptr [ebx+14h]

Any macro or simplification?

Thanks.

Tedd

If you do "assume edi:ptr WINDOWCLASS" then you can do "[edi].lpszClassName" without the need for the struct element offsets (assuming you're including windows.inc; otherwise define the structures as normal.) Don't forget to use "assume edi:nothing" when you finish with edi as that pointer, otherwise you'll get warnings.
I suppose you could define your own function-table-struct along the same lines.

P.S. ExitProcess takes one parameter, not zero :P
No snowflake in an avalanche feels responsible.

ThoughtCriminal

That's a = sign, only numeric equates.  What that means is:

calll [ebp]+Exitprocess  = call [ebp+0]

What I'm looking for is a macro that does not generate code but an offset table with hopefully easier insertion than:

o1 = o0+(4*4) size of each member of the address table (4 bytes)*4 api names in the previous table = start of next table
   Direct3DCreate9 = o1+0  so 4*4+0 = 16 = Direct3DCreate9

The extra work is so I can add a new api in the middle of a list without having to change the offsets of the whole list.  And makes is harder to accidentally use a duplicate offset value that could lead to a hard to find bug.

I will try your assume edi:ptr WINDOWCLASS idea, as long as the resulting call is 3 bytes(and it should be), I may use your method.

Thanks.







Tedd

So?


F0_TABLE struct
    pGetCommandLine DWORD ?
    pGetLastError DWORD ?
    pGetModuleHandle DWORD ?
F0_TABLE ends

.data?
FUNC0 F0_TABLE <>

.code
;;..FUNC0 needs filling in

mov ebp,OFFSET FUNC0
assume ebp:ptr F0_TABLE

call [ebp].pGetCommandLine

assume ebp:nothing


{syntax might need some tweaking, I haven't actually tested it.}
No snowflake in an avalanche feels responsible.

ThoughtCriminal

Looks like ASSUME wont work because you can ASSUME to the middle of a structure:

What I get:

00401006 8B 2D 04 40 40 00 mov         ebp,dword ptr [api+4 (404004h)]
API STRUC
n4 dword ?
STRUC   ZERO
zr dword ?
ENDS 
p4 dword ?
API ENDS

assume ebp:ptr API

call [ebp].n4
0040100C FF 55 00         call        dword ptr [ebp]
call [ebp].ZERO.zr
0040100F FF 55 04         call        dword ptr [ebp+4]
call [ebp].p4
00401012 FF 55 08         call        dword ptr [ebp+8]

What I want:

00401006 8B 2D 04 40 40 00 mov         ebp,dword ptr [api+4 (404004h)]
assume ebp:ptr API

call [ebp].n4
0040100C FF 55 FC         call        dword ptr [ebp-4]
call [ebp].ZERO.zr
0040100F FF 55 00         call        dword ptr [ebp]
call [ebp].p4
00401012 FF 55 04         call        dword ptr [ebp+4]


The question is 0 to 255 the same as -7f t0 7f if its the same might as well use a 0 based approach.

Too tired to think about it now.  Thanks.

u

Btw, you can make enumerations in MASM via a struct:


MyEnum struct
NONE db ? ; = 0
ONE db ? ; = 1
TWO db ? ; = 2
THREE db ? ; = 3
.... and so on
MyEnum ends

....
mov eax,MyEnum.TWO ; assembles into  mov eax,2

RadASM supports intellisense for the above line


I usually name my enumerating-structs with a starting $, so the above enum would be $MyEnum, to make it clear to myself that this is an enumeration, and not a struct.
Please use a smaller graphic in your signature.

ThoughtCriminal

You're right!!! that what I was seeing when I was making my tests.  It is still 0 based, but I could still get 63~64 3 byte calls per STRUCT
(256/ byte size of 32 bit ptr = 64) 

Now I'll just have to expriment becuase I pretty sure if I use negative offsets I can extend that to 128 (well 127 or 126 depending on where the 0th element is).

Thanks.