Hello everyone
First, I'm sorry for my English :biggrin:
I put Struct:
ItemType Struct
hName dd ?
hParent dd ?
hPrevItem dd ?
hNextItem dd ?
hObject dd ?
ItemType ENDS
Then I added VAR..:
FirstItem dd ?
and ..
invoke GetProcessHeap
invoke HeapAlloc, eax, NULL, SIZEOF ItemType
mov FirstItem ,eax
mov esi, FirstItem
assume esi:PTR ItemType
m2m [esi].hName ,chr$("My First Item")
assume esi: nothing
so
I think that the first dword is hName
If I used
mov edx, FirstItem
mov ecx ,dword ptr [edx]
fn MessageBox,0,ecx,0,MB_OK
I get the result
my Question ?
What is the way to get this result by Macro ?
Set_ macro C_:req
??P InStr <C_>, <:>
if ??P ne 0
??Name SubStr <C_>, 1, ??P - 1
ifdef ??Name
mov edx, ??Name
mov ecx ,dword ptr [edx]
; ??TMP TEXTEQU @CatStr(ecx) I test this the result is "ecx"
; @CatStr(<fn MessageBox,0,>,@CatStr(!",@SubStr(%??TMP,1),!"),<,0,MB_OK >)
@CatStr(<fn MessageBox,0,>,@CatStr(!",@SubStr(%ecx,1),!"),<,0,MB_OK >)
endif
else
.err <Set error syntax !" : " missing >
endif
endm
I want to get the text that is in the PTR ecx
fn MessageBox,0,"My First Item",0,MB_OK
I do not want one of the following results
fn MessageBox,0,"ecx",0,MB_OK
or : fn MessageBox,0,ecx,0,MB_OK
Thank you
Quote from: mabdelouahab on November 09, 2013, 10:28:42 AMIf I used
mov edx, FirstItem
mov ecx ,dword ptr [edx]
fn MessageBox,0,ecx,0,MB_OK
I get the result
my Question ?
yes, ECX will be loaded with the pointer to your string "My First Item". This pointer is then passed to MessageBox().
Quote from: mabdelouahab on November 09, 2013, 10:28:42 AM
What is the way to get this result by Macro ?
actual a macro is not really needed here, bcause MASM has already a simple method to access structure members:
e.g.:
mov ecx,pointer to structure
mov eax,[ecx].StructureName.MemberName
or
invoke Fnc,[ecx].StructureName.MemberName,...
Quote from: mabdelouahab on November 09, 2013, 10:28:42 AMI want to get the text that is in the PTR ecx
fn MessageBox,0,"My First Item",0,MB_OK
I do not want one of the following results
fn MessageBox,0,"ecx",0,MB_OK
or : fn MessageBox,0,ecx,0,MB_OK
that is not possible - macros are expanded while assembling and not when the code is executed.
Thank you qWord
Quote from: qWord on November 09, 2013, 10:59:21 AM
that is not possible - macros are expanded while assembling and not when the code is executed.
Important information
I've been using one of two methods
mov edx, pointer to structure
assume edx:PTR StructureName
mov eax , [edx].MemberName
assume edx: nothing
or: ...
mov edx, pointer to structure
mov eax ,(StructureName ptr [edx]).MemberName
but I want to use the name of the Structure, variable, save it in the first DWORD
To be used as a variable, Like :
....
[esi].hName ,chr$("StructureName")
....
mov edx, pointer to structure
mov ecx ,DWORD PTR [EDX] ;<==[esi].hName "StructureName"
assume edx:PTR [ecx]
mov eax , [edx].MemberName
assume edx: nothing
or: ...
mov edx, pointer to structure
mov ecx ,DWORD PTR [EDX] ;<==[esi].hName "StructureName"
mov eax ,([ecx] ptr [edx]).MemberName
Is that possible?
More simply,
I want to use
Set_ macro C_:req ,Arg
??P InStr <C_>, <:>
if ??P ne 0
??Name SubStr <C_>, 1, ??P - 1
??MemberName SubStr <C_>, ??P + 1
ifdef ??Name
mov edx, ??Name
mov ecx ,dword ptr [edx] ;<==[esi].hName "StructureName"
assume edx:PTR @CatStr( @SubStr(%ecx,1) )
m2m [edx].??MemberName,Arg
assume edx: nothing
endif
else
.err <Set error syntax !" : " missing >
endif
endm
For:
Set_ FirstItem:MemberName,5
What a way to use PTR to structname: variable ?
For Ex: in ObjAsm32 ==> " OCall "
I do not want to use fresh code, because I perfected the VB.NAT, and I would like to re-create my projects using MASM32, I have not used it before, but I want mastery
Thank you all ...
I modified CLASS , located in the Objects.INC, as follows:
CLASS_ MACRO CName:REQ , Abiv:VARARG
IFNB <Abiv>
AbvNa TEXTEQU <Abiv>
ELSE
AbvNa TEXTEQU <CName>
ENDIF
Class TEXTEQU <CName>
.data
@CatStr(<Interface_>, CName, < db >, @CatStr(!",@SubStr(%Class,1),!"),<,0>) ;<==== StructureName
@CatStr( CName, < STRUC >)
Interface__ dd ? ;<=========================== ptr to StructureName
ENDM
The same for,
BEGIN_INIT_ MACRO
LOCAL sz1
LOCAL sInterf
sz1 CATSTR Class,<_initdata LABEL BYTE>
sInterf CATSTR < dd OFFSET Interface_>,Class ;<==== init PTR To StructureName=============
sz1
sInterf ;<================================================
ENDM
To be able to use FirstItem:MemberName without StructureName, like Set_ Macro
Set_ FirstItem:MemberName,5
Quote from: mabdelouahab on November 09, 2013, 05:20:49 PM
To be used as a variable, Like :
....
[esi].hName ,chr$("StructureName")
....
mov edx, pointer to structure
mov ecx ,DWORD PTR [EDX] ;<==[esi].hName "StructureName"
assume edx:PTR [ecx]
mov eax , [edx].MemberName
assume edx: nothing
or: ...
mov edx, pointer to structure
mov ecx ,DWORD PTR [EDX] ;<==[esi].hName "StructureName"
mov eax ,([ecx] ptr [edx]).MemberName
Is that possible?
Yes, but I'd suggest a persistent register like ebx:
mov ebx, eax ; eax=pointer to RECT structure
rc equ <[ebx.RECT]> ; from now on you can use rc.member
mov rc.left, 123
mov rc.bottom, ecx
No assume needed, and it works for all kinds of structures.
Quote from: jj2007 on November 09, 2013, 07:18:59 PM
Yes, but I'd suggest a persistent register like ebx:
mov ebx, eax ; eax=pointer to RECT structure
rc equ <[ebx.RECT]> ; from now on you can use rc.member
mov rc.left, 123
mov rc.bottom, ecx
No assume needed, and it works for all kinds of structures.
hi jj2007
If I have to create: ( for ex ... )
CLASS_ TestO
CMETHOD First ;
CMETHOD NextM ;
A dd ?
TestO ENDS
CLASS_ ItemType
hName dd ?
hParent dd ?
hPrevItem dd ?
hNextItem dd ?
hObject dd ?
ItemType ENDS
And also:
FirstItem dd ? ;<== ItemType
test_ dd ? ;<== TestO
The result that I want to be accessed ( Without the use of Structname) is
set_ FirstItem: hObject,10
set _ test_:A,33
I want to use a then hidden ( Interface__ ) in CLASS_,and I put the name of Struct, and used it in the set_ MACRO
Is there any reason to not use ObjAsm32? It also supports the COM ABI.
What you are trying to do is possible, as long as working with correctly typed variables and expressions. The types (class/structure name and the corresponding pointer type) must be recorded for later compare.
??_glbl_cntr = 0
class macro name:req,ptrName
??_current_class TEXTEQU <name>
??_class_ptr_name TEXTEQU <ptrName>
name struct
endm
end_class macro
??_current_class ends
;/**
; * create textmacros that holds the class name (structure name)
; * and the pointer type (PT typedef ptr Class)
; */
@CatStr(<glbl_class_name_>,%??_glbl_cntr) TEXTEQU ??_current_class
IFB ??_class_ptr_name
;/* default name: class name prefixed by "P" */
@CatStr(<P>,%??_current_class) typedef ptr ??_current_class
@CatStr(<glbl_class_ptrType_>,%??_glbl_cntr) TEXTEQU @CatStr(<P>,%??_current_class)
ELSE
;/* user defined name */
??_class_ptr_name typedef ptr ??_current_class
@CatStr(<glbl_class_ptrType_>,%??_glbl_cntr) TEXTEQU ??_class_ptr_name
ENDIF
??_glbl_cntr = ??_glbl_cntr + 1
endm
; do not use EAX and ECX as value
set macro item,value
??_pos1 INSTR <&item>,<:>
IFE ??_pos1
.err <syntax error: missing colon>
EXITM
ENDIF
??_object SUBSTR <&item>,1,??_pos1-1
??_member SUBSTR <&item>,??_pos1+1
??_result = 0
??_cntr = 0
REPEAT ??_glbl_cntr
;/* compare recorded types */
IF (type ??_object) EQ (type @CatStr(<glbl_class_name_>,%??_cntr))
??_result = 1 ; ??_object is a structure
EXITM
ELSEIF (type ??_object) EQ (type @CatStr(<glbl_class_ptrType_>,%??_cntr))
??_result = 2 ; ??_object is a pointer to structure
EXITM
ENDIF
??_cntr = ??_cntr + 1
ENDM
IFE ??_result
.err <unkown class>
ELSEIF ??_result EQ 1
IF (opattr value) AND 1010y
;/* value is a memory operator */
mov eax,value
% mov &??_object&.&??_member&,eax
ELSE
;/* value is an immediate expression or register */
% mov &??_object&.&??_member&,value
ENDIF
ELSEIF ??_result EQ 2
??_class_name TEXTEQU @CatStr(<glbl_class_name_>,%??_cntr)
mov ecx,??_object
IF (opattr value) AND 1010y
mov eax,value
% mov [ecx].&??_class_name&.&??_member&,eax
ELSE
% mov [ecx].&??_class_name&.&??_member&,value
ENDIF
ENDIF
endm
class Item
hName dd ?
hParent dd ?
hPrevItem dd ?
hNextItem dd ?
hObject dd ?
end_class
; example usage
.data?
item PItem ? ; ptr to Item structure
item2 Item <> ; Item structure
.code
main proc
set item:hName,123
set item2:hObject,edx
mov ebx,item
;/* some syntax variations accepted by MASM */
set PItem ptr ebx:hParent,edx
set (Item ptr [ebx]):hParent,123
set [PItem ptr ebx]:hParent,456
exit
main endp
Thank you very much qWord
Always provide us with ideas
so
Through your help,
Do not I change the CLASS MACRO, and no other ...
I managed to reach the following method SET
To create a new object case:
SET hNew = NEW TestO
or:
SET hNew = NEW TestO,14 ; If TESTO.INIT = Args
To give a value to a variable
SET hNew.A = 88
SET hNew.A = eax
To a function call
SET hNew.First,235,333
All this without a name StructName
..
SET macro Str_:req, Args:vararg
??_posEQ INSTR <&Str_>,<=>
IFE ??_posEQ
??_posDot INSTR 1, <&Str_>,<.> ;<=================== INVOKE PROC
IFE ??_posDot
.err <syntax error: missing . >
ELSE
??_object SUBSTR <&Str_>,1,??_posDot-1
??_Proc SUBSTR <&Str_>,??_posDot+1
% IFNDEF @CatStr(??_object)
% .err <syntax error: &??_object& indefined >
% ELSEIFNDEF @CatStr(<Class_Of_>,&??_object)
% .err < Object not create by " SET NEW" >
ELSE
Class__ TEXTEQU @CatStr(<Class_Of_>,&??_object)
% @CatStr(<mov ecx ,>, %??_object)
% invoke ( &Class__& PTR [ecx]).&??_Proc&,&??_object&,Args
ENDIF
ENDIF
ELSE
??_posNEW INSTR <&Str_>,< NEW > ;<=================== SET VALUE
IFE ??_posNEW
??_posDot INSTR 1, <&Str_>,<.>
IF (??_posDot eq 0) or (??_posDot gt ??_posEQ)
.err <syntax error: missing . >
ELSE
??_object SUBSTR <&Str_>,1,??_posDot-1
??_MEMBER SUBSTR <&Str_>,??_posDot+1,??_posEQ-??_posDot-1
??_Value SUBSTR <&Str_>,??_posEQ + 1
% IFNDEF @CatStr(??_object)
% .err <syntax error: &??_object& indefined >
% ELSEIFNDEF @CatStr(<Class_Of_>,&??_object)
% .err < Object not create by " SET NEW" >
ELSE
Class__ TEXTEQU @CatStr(<Class_Of_>,&??_object)
% mov ecx,&??_object&
% mov eax, &??_Value&
% mov ( Class__ PTR [ecx]).&??_MEMBER&, eax
ENDIF
ENDIF
ELSE
??_object SUBSTR <&Str_>,1,??_posEQ-1 ;<=================== NEW Object
??_Class SUBSTR <&Str_>,??_posNEW+4
% IFNDEF @CatStr(??_Class)
% .err <syntax error: &??_Class& indefined >
% ELSEIFNDEF @CatStr(??_object)
% .err <syntax error: &??_object& indefined >
ELSE
% Class_Of_&??_object& TEXTEQU <&??_Class&>
IFNB <Args>
% mov eax,$NEW(%??_Class,Args)
ELSE
% mov eax,$NEW(%??_Class)
ENDIF
% mov &??_object&,eax
ENDIF
ENDIF
ENDIF
endm
Thank you all
Hello all
I was able to add GET macro, but I have a small problem ;)
If it is used:
GET eax =hNew.A
, the result is: OK
But if it is used,
GET eax = hNew.A
, the result is: error
What a way to remove the SPACE, to avoid this
GET macro Str_:req, Args:vararg
??_posEQ INSTR <&Str_>,<=>
IFE ??_posEQ
.err <syntax error: missing = >
ELSE
??_posDot INSTR 1, <&Str_>,<.>
IF (??_posDot eq 0) ;or (??_posDot lt ??_posEQ)
.err <syntax error: missing . >
ELSE
??_object SUBSTR <&Str_>,??_posEQ+1,??_posDot-??_posEQ-1
??_MEMBER SUBSTR <&Str_>,??_posDot+1
??_Value SUBSTR <&Str_>,1,??_posEQ + -1
% IFNDEF @CatStr(??_object)
% .err <syntax error: &??_object& indefined >
% ELSEIFNDEF @CatStr(<Class_Of_>,&??_object)
% .err < Object not create by " SET NEW" >
ELSE
Class__ TEXTEQU @CatStr(<Class_Of_>,&??_object)
% mov ecx,&??_object&
% mov eax,( Class__ PTR [ecx]).&??_MEMBER&
ENDIF
ENDIF
ENDIF
endm
But for SET macro succeeded with me.
SET hNew = NEW TestO,14
SET hNew.A = 332
GET eax =hNew.A
fn MessageBox,0,str$(eax),0,MB_OK
SET hNew.First,235,333
I want only to add CHECK
If I used with the CLASS or just Struct , the difference between the two, is that CLASS, a INIT call startup
How can I know that in the struct, there is a INIT proc
I want to use IFDEF, but give me the same result
IFDEF hNew.init <== OK, IFDEF hNEW.H0254555454__ <== OK
When I could make sure INIT Proc
I can use with CLASS (For Ex: TestO)
mov eax,$NEW(TestO)
and With simple STRUCT use (For ex: RECT)
invoke GetProcessHeap
invoke HeapAlloc, eax, NULL, SIZEOF RECT
mov hNew,eax
Here is SET macro
SET macro Str_:req, Args:vararg
??_posEQ INSTR <&Str_>,<=>
IFE ??_posEQ
??_posDot INSTR 1, <&Str_>,<.> ;<=================== INVOKE PROC
IFE ??_posDot
.err <syntax error: missing . >
ELSE
??_object SUBSTR <&Str_>,1,??_posDot-1
??_Proc SUBSTR <&Str_>,??_posDot+1
% IFNDEF @CatStr(??_object)
% .err <syntax error: &??_object& indefined >
% ELSEIFNDEF @CatStr(<Class_Of_>,&??_object)
% .err < Object not create by " SET NEW" >
ELSE
Class__ TEXTEQU @CatStr(<Class_Of_>,&??_object)
% @CatStr(<mov ecx ,>, %??_object)
% invoke ( &Class__& PTR [ecx]).&??_Proc&,&??_object&,Args
ENDIF
ENDIF
ELSE
??_posNEW INSTR <&Str_>,< NEW > ;<=================== SET VALUE
IFE ??_posNEW
??_posDot INSTR 1, <&Str_>,<.>
IF (??_posDot eq 0) or (??_posDot gt ??_posEQ)
.err <syntax error: missing . >
ELSE
??_object SUBSTR <&Str_>,1,??_posDot-1
??_MEMBER SUBSTR <&Str_>,??_posDot+1,??_posEQ-??_posDot-1
??_Value SUBSTR <&Str_>,??_posEQ + 1
% IFNDEF @CatStr(??_object)
% .err <syntax error: &??_object& indefined >
% ELSEIFNDEF @CatStr(<Class_Of_>,&??_object)
% .err < Object not create by " SET NEW" >
ELSE
Class__ TEXTEQU @CatStr(<Class_Of_>,&??_object)
% mov ecx,&??_object&
% mov eax, &??_Value&
% mov ( Class__ PTR [ecx]).&??_MEMBER&, eax
ENDIF
ENDIF
ELSE
??_object SUBSTR <&Str_>,1,??_posEQ-1 ;<=================== NEW Object
??_Class SUBSTR <&Str_>,??_posNEW+4
% IFNDEF @CatStr(??_Class)
% .err <syntax error: &??_Class& indefined >
% ELSEIFNDEF @CatStr(??_object)
% .err <syntax error: &??_object& indefined >
ELSE
% Class_Of_&??_object& TEXTEQU <&??_Class&>
IFNB <Args>
% mov eax,$NEW(%??_Class,Args)
ELSE
% mov eax,$NEW(%??_Class)
ENDIF
% mov &??_object&,eax
ENDIF
ENDIF
ENDIF
endm
Hi mabdelouahab,
No offense, but perhaps you could use the LOCAL keyword instead of all these ?? labels? Your macros would become much more readable...
Also, the ampersand as in <&Str_> is not necessary - <Str_> does the same. Use it only in situations like print "The object &Str_ is undefined"
I have tried to reproduce your problem, but it seems to work with and without spaces:
include \masm32\include\masm32rt.inc
include SetMac.asm
GET macro Str_:req, Args:vararg
LOCAL ins, PosDot, obj, member, val
ins INSTR <Str_>, <=>
IFE ins
.err <syntax error: missing = >
ELSE
PosDot INSTR <Str_>, <.>
IFE PosDot
.err <syntax error: missing . >
ELSE
% IFNDEF @SubStr(<Str_>, ins+1, PosDot-ins-1)
% echo ## syntax error: [@SubStr(<Str_>, ins+1, PosDot-ins-1)] is undefined, sorry ##
.err
% ELSEIFNDEF @CatStr(<Class_Of_>, &obj)
% echo ## [@SubStr(<Str_>, ins+1, PosDot-ins-1)] object not created by " SET NEW" ##
.err
ELSE
member SUBSTR <Str_>, PosDot+1
val SUBSTR <Str_>, 1, ins + -1 ; should be plus 1, i.e. after "="?
Class__ TEXTEQU @CatStr(<Class_Of_>,&obj)
mov ecx, obj
; mov eax, ( Class__ PTR [ecx]). member
mov eax, val
mov ( Class__ PTR [ecx]).member, eax
ENDIF
ENDIF
ENDIF
ENDM
MyStruct STRUCT
A dd ?
B dd ?
MyStruct ENDS
.data?
hNew MyStruct <>
.code
if 0
The three GET calls generate these error messages:
## syntax error: [hUndefined] is undefined, sorry ##
## [hNew] object not created by " SET NEW" ##
## [ hNew] object not created by " SET NEW" ##
endif
start:
GET eax =hUndefined.A
GET eax =hNew.A
GET eax = hNew.A
exit
end start
Code attached.