News:

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

get an adress with a pointer on a strucrture

Started by ToutEnMasm, August 26, 2011, 05:01:34 PM

Previous topic - Next topic

ToutEnMasm


Here is the c++ form
Quote
; Line 444  **                        InterlockedIncrement(&appContext->lPendingWrites);
   mov   eax,appContext
   add   eax, 52               ; 00000034H
   push   eax
   call InterlockedIncrement         
appContext is  dword with the adress of  a structure (APP_CONTEXT   lea edx, [eax].APP_CONTEXT.PendingWrites)

Is there a way to do the same thing with masm ?
I have try:
appContext ptr APP_CONTEXT
Lea edx,appContext.APP_CONTEXT.PendingWrites                  and just made a crash !







l




qWord

mov edx,appContext
lea edx,[edx].APP_CONTEXT.PendingWrites
FPU in a trice: SmplMath
It's that simple!

dedndave

appContext ptr APP_CONTEXT

???

is that supposed to be an ASSUME directive ?

ToutEnMasm


I want to write an invoke with the c++ code.
What i have  write is various test , appContext ptr APP_CONTEXT is one of them.
Miss
Quote
APP_CONTEXT   STRUCT
.......................
   lPendingWrites DWORD ?
   bReceiveDone DWORD ?
   crSection RTL_CRITICAL_SECTION <>
APP_CONTEXT      ENDS

PESSAI TYPEDEF ptr APP_CONTEXT
.data
cdfg APP_CONTEXT <>
aContext PESSAI  cdfg

.code
   PUSH [aContext].APP_CONTEXT.lPendingWrites ;just crash

My actual soluce is to use a macro ,but perhaps is something better ?



ToutEnMasm


Here is the macro i use:
Quote
;the array of pointer allow to pass the limit of three registers usable for the call
;arg1 dword pointer,arg2 offset in structure,offset of an array of pointer
PDR MACRO arg1,arg2,arg3
   push edx
   mov edx,arg1
   add edx,52        ;APP_CONTEXT.lPendingWrites
   mov [BUFIDR+arg3],edx
   pop edx
   EXITM <dword ptr [BUFIDR+arg3]>
ENDM

qWord

you must load the pointer into a register before usage!
APP_CONTEXT   STRUCT
.......................
   lPendingWrites DWORD ?
   bReceiveDone DWORD ?
   crSection RTL_CRITICAL_SECTION <>
APP_CONTEXT      ENDS
PAPP_CONTEXT TYPEDEF ptr APP_CONTEXT

.data
cdfg APP_CONTEXT <>
pContext PAPP_CONTEXT  OFFSET cdfg

.code
   mov eax,pContext
   PUSH [eax].APP_CONTEXT.lPendingWrites


BTW: it is maybe better to use use a naming convention, that  makes clear what a label represent (e.g. aContext  -> pContext).
FPU in a trice: SmplMath
It's that simple!

ToutEnMasm

I couldn't use registers for that.Many parameters of a function can need a register for that and there is only three registers usble easily.

Here is  sample  of use of the macro.
Quote
.data
BUFIDR dd 20 dup (0)  ;
.code
   invoke appel,PVAL (aContext,ESSAI.ert,0),PADR(aContext,APP_CONTEXT.lPendingWrites,4)

appel is just  a proc for debug use .






qWord

Quote from: ToutEnMasm on August 26, 2011, 06:33:52 PM
I couldn't use registers for that.Many parameters of a function can need a register for that and there is only three registers usble easily.
you must use registers! - if needed, preserve them on the stack or in a local varibale.
FPU in a trice: SmplMath
It's that simple!

ToutEnMasm

#8
you must use registers!
It's not a law.
I push dword in data with my macro and this work.
If masm could be better , i would have also a better soluce.

qWord

Surely you can push memory operand on the stack - all you need is the address as an immediate value or in a register. In your case the pointer is stored in memory, thus you need to first load him in a register.
Your problem can be solved by simply working with the structure's label cdfg instead of the pointer aContext.
FPU in a trice: SmplMath
It's that simple!

ToutEnMasm

Quote
Your problem can be solved by simply working with the structure's label cdfg instead of the pointer aContext.
If windows give you a pointer on  structure , you cannot do thet.
The sample is just here to show the problem.The real one is here:
http://www.masm32.com/board/index.php?topic=17108.msg144961#msg144961
C++ use a lot of things like that and masm need to find other ways to do the same thing .



qWord

Quote from: ToutEnMasm on August 26, 2011, 07:23:26 PMIf windows give you a pointer on  structure , you cannot do thet.
exactly - in this case there is no way around using a register for accessing the structure's members (x86-32 architecture!).
I do not understand you problem - what is so complicated on using a register for this task?
FPU in a trice: SmplMath
It's that simple!

clive

I don't think this has the desired effect

Quote from: qWord
.code
   mov eax,pContext
   PUSH [eax].APP_CONTEXT.lPendingWrites

Unfortunately the x86 doesn't have a PEA instruction (Push Effective Address)


.code
   mov eax,pContext
   lea eax,[eax].APP_CONTEXT.lPendingWrites
   push eax


But you're right, you have to do this with register(s), typically one scratch one is enough as you push things onto the stack, and EAX will presumably be overwritten by the function being called, per the EBI. ECX,EDX should be fair game too.
It could be a random act of randomness. Those happen a lot as well.

ToutEnMasm

I have found what I searched
Windows give you a pointer on  a structure,you put it in aContext  (aContext dd  )
Then you create a constant with this name:
Quote
DECLARE_aContext TEXTEQU <APP_CONTEXT>
APP_CONTEXT is the name of the structure who is referenced by aContext
The following macro allow you to extract an adress of the structure easily.
Quote
;the array of pointer allow to pass the limit of three registers usable for the call
;arg1 dword pointer,arg2 offset in structure,offset of an array of pointer
PADR MACRO arg1,arg2,arg3
   computeoffset CATSTR <DECLARE_>,<arg1>,<.>,<arg2>
   push edx
   mov edx,arg1
   add edx,computeoffset         
   mov [BUFIDR+arg3],edx
   pop edx
   EXITM <dword ptr [BUFIDR+arg3]>
ENDM


Here is the complet source code
Quote
APP_CONTEXT   STRUCT
   dwStructType DWORD ?
   mainContext DWORD ?
   hRequest DWORD ?
   hEvent DWORD ?
   pszOutBuffer DWORD ?
   dwDownloaded DWORD ?
   dwRead DWORD ?
   dwWritten DWORD ?
   dwReadOffset DWORD ?
   dwWriteOffset DWORD ?
   hFile DWORD ?
   hRes DWORD ?
   dwState DWORD ?
   lPendingWrites DWORD ?
   bReceiveDone DWORD ?
   crSection RTL_CRITICAL_SECTION <>
APP_CONTEXT      ENDS
DECLARE_aContext TEXTEQU <APP_CONTEXT>

;the array of pointer allow to pass the limit of three registers usable for the call
;arg1 dword pointer,arg2 offset in structure,offset of an array of pointer
PADR MACRO arg1,arg2,arg3
   computeoffset CATSTR <DECLARE_>,<arg1>,<.>,<arg2>
   push edx
   mov edx,arg1
   add edx,computeoffset         
   mov [BUFIDR+arg3],edx
   pop edx
   EXITM <dword ptr [BUFIDR+arg3]>
ENDM
PVAL MACRO arg1,arg2,arg3
   computeoffset CATSTR <DECLARE_>,<arg1>,<.>,<arg2>
   push edx
   mov edx,arg1
   mov edx,DWORD PTR [edx+computeoffset]
   mov [BUFIDR+arg3],edx
   pop edx
   EXITM <dword ptr [BUFIDR+arg3]>
ENDM


   .const
   .data
   
BUFIDR dd 20 dup (0)   
cdfg APP_CONTEXT <>
aContext dd  cdfg

   
   

   .code
   start:
   mov cdfg.lPendingWrites,35h
   invoke appel,PVAL(aContext,lPendingWrites,0),PADR(aContext,lPendingWrites,4)
   invoke ExitProcess,0


;################################################################
appel PROC  atruc:DWORD,btruc:DWORD
      Local  retour:DWORD
         mov retour,1
   mov eax,atruc      ;value of APP_CONTEXT.lPendingWrites    eax = 35h
   mov eax,btruc     ;adress of APP_CONTEXT.lPendingWrites   
   mov edx,[eax]   ; edx = 35h
Findetruc:
         mov eax,retour
         ret
appel endp




drizz

mov edx,appContext
invoke InterlockedIncrement, addr [edx].APP_CONTEXT.lPendingWrites
The truth cannot be learned ... it can only be recognized.