Home > Software engineering >  In MASM, how to access the longValue member within the PDH_FMT_COUNTERVALUE struct?
In MASM, how to access the longValue member within the PDH_FMT_COUNTERVALUE struct?

Time:11-10

Working on a project to get the current CPU load.
I'm having difficulty accessing the longvalue in this struct: (sizeof is 16 bytes)

   PDH_FMT_COUNTERVALUE STRUCT 8
                   CStatus                        DWORD ?
                   UNION                         
                   longValue                      DWORD ?
                   doubleValue                    QWORD ?
                   largeValue                     QWORD ?
                   pAnsiStringValue               QWORD ?
                   pWideStringValue               QWORD ?
                   ENDS                          
   PDH_FMT_COUNTERVALUE ENDS

Initially, I tried using this MASM code but the CPU usage was always 0.
(I think it was looking at the member padding after the first 4 bytes for CStatus)

              LOCAL           value:PDH_FMT_COUNTERVALUE
              ...
              LEA             R9,value
              MOV             EAX,DWORD PTR [R9 PDH_FMT_COUNTERVALUE.longValue]
              MOV             cput,RAX

However, by adding 4, it correctly finds the longvalue:

              LOCAL           value:PDH_FMT_COUNTERVALUE
              ...
              LEA             R9,value
              MOV             EAX,DWORD PTR [R9 PDH_FMT_COUNTERVALUE.longValue 4] ;; <--  4 added here
              MOV             cput,RAX

Notice the following offset resolves to 8 overall

PDH_FMT_COUNTERVALUE.longValue 4 ;; dword ptr [r9 8]

For comparison, the MSVC compiler generates the correct 8 offset:
(It dereferences a byte, even though it's defined as a DWORD)

cput = value.longValue;
movzx       eax,byte ptr [value 8h]  
mov         byte ptr [cput],al  

Question

This code looks hackish [R9 PDH_FMT_COUNTERVALUE.longValue 4], so is there a more legit method to refer to the longvalue member directly in MASM?

EDIT

Possible solution, manually padding the struct allows access to the longValue.

   PDH_FMT_COUNTERVALUE STRUCT 8
                   CStatus                        DWORD ?
                   padding                        BYTE 4 DUP (?)
                   UNION                         
                   longValue                      DWORD ?
                   doubleValue                    QWORD ?
                   largeValue                     QWORD ?
                   pAnsiStringValue               QWORD ?
                   pWideStringValue               QWORD ?
                   ENDS                          
   PDH_FMT_COUNTERVALUE ENDS

CodePudding user response:

Unfortunately I'm not aware of a cleaner solution than this, but this should work:

COUNTERVALUE UNION                    
    longValue                      DWORD ?
    doubleValue                    QWORD ?
    largeValue                     QWORD ?
    pAnsiStringValue               QWORD ?
    pWideStringValue               QWORD ?
COUNTERVALUE ENDS                          

PDH_FMT_COUNTERVALUE STRUCT 8
    CStatus                        DWORD ?
    COUNTERVALUE                   <>
PDH_FMT_COUNTERVALUE ENDS
  • Related