Hi
I try to code a plugin and can only found a c++ example
have this procedur 4 dwords?
static int menu_handler( t_table* pTable, wchar_t* pName, ulong index, int nMode )
{
masm32:
Menu_handler Proc pTable:DWORD,pName:DWORD,index:DWORD,nMode:DWORD
is this Right?
This should help you:
http://www.masm32.com/board/index.php?topic=5594.0
No Horton
this is for calling a decorated C++ function from MASM.
I translate this procedur from c++ to masm32 and i know not if have this procedur 4 dWords?!
The short answer: probably.
The long answer: you can't ever say for sure. C++ compilers can pretty much pass things anyway they please, so unless they specifically call it out somewhere, you just have to hope that they do it the "normal" way.
-r
what for a normal way?
http://en.wikipedia.org/wiki/X86_calling_conventions#cdecl
By value, right to left, on the stack, no 'this' pointer.
Thanks i have it solved with
Menu_handler Proc C pTable:DWORD,pName:DWORD,index:DWORD,nMode:DWORD
Now have i a other question to fill this structur
C++
typedef struct t_menu { // Menu descriptor
wchar_t *name; // Menu command
wchar_t *help; // Explanation of command
int shortcutid; // Shortcut identifier, K_xxx
MENUFUNC *menufunc; // Function that executes menu command
struct t_menu *submenu; // Pointer to descriptor of popup menu
union {
ulong index; // Argument passed to menu function
HMENU hsubmenu; // Handle of pulldown menu
};
} t_menu;
;// menu that will appear in the main menu. Note that this menu
;// must be static and must be kept for the whole duration
static t_menu mainmenu[] = {
{ L"Menuentry",
L"MenuInfo",
0, MenuentryCallback, NULL, 0 },
{ L"Menuentry2",
L"MenuInfo2",
0, Menuentry2Callback, NULL, 0 },
{ L"|Menuentry3",
L"MenuInfo3",
0, Menuentry3Callback, NULL, 0 },
{ NULL, NULL, 0, NULL, NULL, 0 }
};
Here is my tryed translate but it works not correct can any Translate it right?
Masm32
t_menu STRUCT
Name1 DWORD ? ; Menu command
help DWORD ? ; Explanation of command
shortcutid DWORD ? ; Shortcut identifier, K_xxx
menufunc DWORD ? ; Function that executes menu command
submenu DWORD ? ; Pointer to descriptor of popup menu
;union t_menu
index DWORD ? ; Argument passed to menu function
hsubmenu DWORD ? ; Handle of pulldown menu
;ENDS
t_menu ENDS
WSTR Menuentry ,"entry"
WSTR MenuentryInfo,"entry info"
WSTR Menuentry2 ,"entry2"
WSTR MenuentryInfo2,"entry info2"
WSTR Menuentry3 ,"entry3"
WSTR MenuentryInfo4,"entry info3"
MainMenu t_menu <Menuentry,MenuentryInfo,NULL,MenuentryCallback,NULL ,0>
t_menu <Menuentry2,MenuentryInfo2,NULL,Menuentry2Callback,NULL ,0>
t_menu <Menuentry3,MenuentryInfo3,NULL,Menuentry3Callback,NULL ,0>
greets
I have found this bug i decomment "union t_menu"
t_menu STRUCT
Name1 DWORD ? ; Menu command
help DWORD ? ; Explanation of command
shortcutid DWORD ? ; Shortcut identifier, K_xxx
menufunc DWORD ? ; Function that executes menu command
submenu DWORD ? ; Pointer to descriptor of popup menu
union t_menu
index DWORD ? ; Argument passed to menu function
hsubmenu DWORD ? ; Handle of pulldown menu
ENDS
t_menu ENDS
How i can fill this index " Argument passed to menu function"?
MainMenu t_menu <Menuentry,MenuentryInfo,NULL,MenuentryCallback,0,1>
If i add the 1 have i this error
error A2138: invalid data initializer
error A2036: too many initial values for structure
RAGDOG,
I can see why you are confused. A C++ Union really has no counterpart in assembly language. Here is the MSDN documentation for: Unions (http://msdn.microsoft.com/en-us/library/5dxy4b7b(v=vs.80).aspx). I never use unions when I code in C++, because they're not that useful. They are a only a convenience Essentially, they give you a way to access some data in several different ways (syntactically). C++ compilers (like Visual Studio) have type checking, and the code will fail to compile if you don't access the union data using one of the declared types (in this case, a ulong or HMENU). In C++, both the ulong and the HMENU are typedef'ed from a DWORD. To convert this to assembly, just ignore the union declaration (delete the union declaration) and leave one or both of the DWORDs in your structure. For the code example you posted, the simplest method would be to just make it a single structure.
union t_menu
index DWORD ? ; Argument passed to menu function
hsubmenu DWORD ? ; Handle of pulldown menu
Here, the index DWORD and the hsubmenu DWORD are referring to the same exact data (DWORD), and so having both types in your structure is redundant. And, of course, the MASM compiler has no idea what a union t_menu is,...
Quote from: baltoro on August 15, 2011, 10:08:10 PM
RAGDOG,
I can see why you are confused. A C++ Union really has no counterpart in assembly language.
It has, it has, but it's tricky and badly documented. The example below, modified from Chapter 5 of the Masm Programming Guide, works just fine with ML (all versions) and gets assembled by JWasm (but yields a different result).
Quoteinclude \masm32\include\masm32rt.inc
ITEMS STRUCT
Iname BYTE 'Item Name'
Inum WORD ?
UNION ITYPE ; UNION keyword appears first
oldtype BYTE 123 ; when nested in structure.
newtype WORD 12345 ; (See "Nested Structures
ENDS ; and Unions," following ).
ITEMS ENDS
.DATA
Item ITEMS <'Bolts', 126> ; Overrides default value of first
; 2 fields; use default of the third field
.code
start: movzx eax, Item.ITYPE.oldtype
inkey str$(eax), " for item.oldtype"
exit
end start
Output: 123 for item.oldtype
Basically. it means you cannot initialise the UNION member in the .data section; instead, you omit it and get the first default value.
::)
Wow,...Thanks, Jochen for saving my ass,... :eek
I had no idea. Must be my Union phobia,...
jj2007,
So, don't initialize it in the DATA section, do it in your code. No limitations.
INCLUDE \masm32\include\masm32rt.inc
ITEMS STRUCT
Iname BYTE ?
Inum WORD ?
UNION ITYPE
oldtype BYTE ?
newtype WORD ?
ENDS
ITEMS ENDS
.DATA
Item ITEMS <>
.CODE
start:
mov Item.ITYPE.oldtype, 123
movzx eax, Item.ITYPE.oldtype
inkey str$(eax), " for item.oldtype"
mov Item.ITYPE.newtype, 12345
movzx eax, Item.ITYPE.newtype
inkey str$(eax), " for item.newtype"
exit
END start
Quote from: GregL on August 16, 2011, 02:55:17 AM
jj2007,
So, don't initialize it in the DATA section, do it in your code. No limitations.
Sure, that is always possible. But still, the documentation steers cautiously away from giving a full example for UNION. They know why. Add the case where the UNION is not the last member of the STRUCT, and the mess is complete :bg
Seems here that the first argument "Iname BYTE " broke the alignment and is responsible of the problem.
Try to put a align directive before to solve it.
Quote from: ToutEnMasm on August 16, 2011, 07:07:49 AM
Seems here that the first argument "Iname BYTE " broke the alignment and is responsible of the problem.
Try to put a align directive before to solve it.
There is no alignment problem, ToutEnMasm.
In the meantime, I found the correct syntax for declaring the UNION:
QuoteItem1 ITEMS <"abcdef", 12345, {99}>
Which does not solve all problems, though. It remains very messy. Inter alia, JWasm produces different values, only the UNION gets initialised by its default value, and I was able to cause an exception in ml.exe version 6.14 simply by writing
QuoteITEMS STRUCT STRUCTALIGN 4
(I know it's a syntax error, but is it worth a GPF? ::))
Have fun. My conclusion is don't use UNIONs, it's too buggy.
include \masm32\include\masm32rt.inc
ITEMS STRUCT
Iname BYTE 'Item Name' ; caution: the text "Item Name" defines the length of Iname, here: 9 chars
Inum WORD 3333h
UNION ITYPE ; UNION keyword appears first
oldtype BYTE 123 ; when nested in structure.
newtype WORD 12345 ; (See "Nested Structures
ENDS ; and Unions," following ).
ITEMS ENDS
.DATA ; see Chapter 5 of Masm Programming Guide
Item1 ITEMS <"abcdef", 12345, {99}> ; Overrides default values
Item2 ITEMS <"",?,{}> ; Should take default values, ok for UNION but no success for string and WORD
.code
start:
; mov edx, offset Item1.Iname ; check in memory...
; int 3
print offset Item1.Iname, " as string (the '90' is part of WORD 12345)", 13, 10
; mov edx, offset Item1.Inum ; the WORD
; int 3
movzx eax, Item1.Inum
print str$(eax), " for Inum", 13, 10
movzx eax, Item1.ITYPE.oldtype
print str$(eax), " for Item1.oldtype", 13, 10
movzx eax, Item1.ITYPE.newtype
print str$(eax), " for Item1.newtype", 13, 10
print offset Item2.Iname, " as string", 13, 10
; mov edx, offset Item2.Inum ; the WORD
; int 3
movzx eax, Item2.Inum
print str$(eax), " for Inum", 13, 10
movzx eax, Item2.ITYPE.oldtype
print str$(eax), " for Item2.oldtype", 13, 10
movzx eax, Item2.ITYPE.newtype
inkey str$(eax), " for Item2.newtype"
exit
end start
An excellent explanation, Jochen.
...Which leaves me wondering,...just why does assembly language have Unions anyway ???
Surely, it can't be just so that it is compatible with C/C++,...
By the way, I was searching google and found this example, showing how to define a UNION nested within a STRUCTURE:
It's probably easier for the MASM compiler to parse. He defines the UNION outside the STRUCTURE, initially.
This is from Kip Irvine: Here (http://www.csie.ntu.edu.tw/~acpang/course/asm_2004/slides/chapt_10_PartI.pdf)
Integer UNION
D DWORD 0
W WORD 0
B BYTE 0
Integer ENDS
FileInfo STRUCT
FileID Integer <>
FileName BYTE 64 DUP(?)
FileInfo ENDS
.data
myFile FileInfo <>
.code
mov myFile.FileID.W, ax
Quote from: baltoro on August 16, 2011, 07:45:38 PM
why does assembly language have Unions anyway ???
Perhaps the best example why and where UNIONs can be handy is here at MSDN (http://msdn.microsoft.com/en-us/library/ms646270%28v=vs.85%29.aspx). Check the differences between the MOUSEINPUT and KEYBDINPUT structures.