flat assembler
Message board for the users of flat assembler.

Index > Macroinstructions > Accessing BitFields in Struct

Author
Thread Post new topic Reply to topic
farrier



Joined: 26 Aug 2004
Posts: 274
Location: North Central Mississippi
farrier 12 Mar 2006, 20:42
While experimenting with the Windows Performance Data Helper (PDH) functions, one of the structures used has a DWORD with 10 bits used to set options. Is there any way withing FASM to set +/or access the bit values of this structure using the struct macro? ConFlags is the DWORD I set up to represent the flags. Here is the structure:

Code:
PDH_BROWSE_DLG_CONFIG   struct  ;typedef struct _BrowseDlgConfig 
        ConFlags                dd      ?       ;{  \\Configuration flags;  
                                        ;DWORD 
                                        ;       bIncludeInstanceIndex  :1;              f
                                        ;       bSingleCounterPerAdd  :1;               t
                                        ;       bSingleCounterPerDialog  :1;            t
                                        ;       bLocalCountersOnly  :1;                 f
                                        ;       bWildCardInstances  :1;                 t
                                        ;       bHideDetailBox  :1;                     t
                                        ;       bInitializePath  :1;                    f
                                        ;       bDisableMachineSelection  :1;           f
                                        ;       bIncludeCostlyObjects  :1;              f
                                        ;       bShowObjectBrowser  :1;                 f
                                        ;       bReserved  :23;                         f
        hWndOwner               dd      ?       ;HWND hWndOwner;                        NULL
        szDataSource            dd      ?       ;LPTSTR szDataSource;
        szReturnPathBuffer      dd      ?       ;LPTSTR szReturnPathBuffer;             szPathBuffer
        cchReturnPathLength     dd      ?       ;DWORD cchReturnPathLength;             MAXPATH
        pCallBack               dd      ?       ;CounterPathCallBack pCallBack;         NULL
        dwCallBackArg           dd      ?       ;DWORD_PTR dwCallBackArg;               NULL
        CallBackStatus          dd      ?       ;PDH_STATUS CallBackStatus;             ERROR_SUCCESS
        dwDefaultDetailLevel    dd      ?       ;DWORD dwDefaultDetailLevel;            PERF_DETAIL_WIZARD
        szDialogBoxCaption      dd      ?       ;LPTSTR szDialogBoxCaption;             "Select a counter to monitor."
PDH_BROWSE_DLG_CONFIG   ends    ;} PDH_BROWSE_DLG_CONFIG, *PPDH_BROWSE_DLG_CONFIG;    


Thanks,

farrier

_________________
Some Assembly Required
It's a good day to code!
U.S.Constitution; Bill of Rights; Amendment 1:
... the right of the people peaceably to assemble, ...
The code is dark, and full of errors!
Post 12 Mar 2006, 20:42
View user's profile Send private message Reply with quote
Reverend



Joined: 24 Aug 2004
Posts: 408
Location: Poland
Reverend 13 Mar 2006, 11:43
You can define constant values like:
Code:
bIncludeInstanceIndex = 0
bSingleCounterPerAdd = 1
bSingleCounterPerDialog = 2
bLocalCountersOnly = 4
bWildCardInstances = 8
...    
And later in code check the value like this:
Code:
pdh PDH_BROWSE_DLG_CONFIG

; set flag
or [pdh.ConFlag], bWildCardInstances

; check if flag was set
test [pdh.ConFlag], bSingleCounterPad
jz flag_is_not_set    
Post 13 Mar 2006, 11:43
View user's profile Send private message Visit poster's website Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid 13 Mar 2006, 12:03
i suggest this way of definition:
Code:
bIncludeInstanceIndex   = 0000b
bSingleCounterPerAdd    = 0001b
bSingleCounterPerDialog = 0010b
bLocalCountersOnly      = 0100b
bWildCardInstances      = 1000b
;etc.

;PS: clear flag
and [...], not bIncludeInstanceIndex
    


Last edited by vid on 13 Mar 2006, 21:10; edited 1 time in total
Post 13 Mar 2006, 12:03
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
farrier



Joined: 26 Aug 2004
Posts: 274
Location: North Central Mississippi
farrier 13 Mar 2006, 14:27
vid,
Reverend,

Thanks for your reponses! Both good--and similar--ideas, I figure this is what is happening in other languages/assemblers "behind the scenes". I'll play around with a few different test/set/clear routines to see which feels better to me.

Thanks again!

farrier

_________________
Some Assembly Required
It's a good day to code!
U.S.Constitution; Bill of Rights; Amendment 1:
... the right of the people peaceably to assemble, ...
The code is dark, and full of errors!
Post 13 Mar 2006, 14:27
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8356
Location: Kraków, Poland
Tomasz Grysztar 13 Mar 2006, 14:39
Check out the BT/BTS/BTR/BTC instructions, they come quite handy for bit manipulations sometimes (there were also very interesting instructions IBTS and XBTS in the early 386 processors, but they soon became removed).
Post 13 Mar 2006, 14:39
View user's profile Send private message Visit poster's website Reply with quote
farrier



Joined: 26 Aug 2004
Posts: 274
Location: North Central Mississippi
farrier 13 Mar 2006, 20:04
Tomasz Grysztar,

Thanks! After looking at these, they seem to be well suited for certain circumstances. I'll probably use all of these methods on different occasions.

Thanks,

farrier

_________________
Some Assembly Required
It's a good day to code!
U.S.Constitution; Bill of Rights; Amendment 1:
... the right of the people peaceably to assemble, ...
The code is dark, and full of errors!
Post 13 Mar 2006, 20:04
View user's profile Send private message Reply with quote
Reverend



Joined: 24 Aug 2004
Posts: 408
Location: Poland
Reverend 13 Mar 2006, 20:20
I suggested test instruction, because if properly used it can act exactly the same as bt instr. but it is AFIK faster.

vid: Yes, you're right about that. I wanted to write sth similar, but with '1 shl 1' ', '1 shl 2', '1 shl 3' Smile. Your solution is the simpliest and probably the most readable.
Post 13 Mar 2006, 20:20
View user's profile Send private message Visit poster's website Reply with quote
Madis731



Joined: 25 Sep 2003
Posts: 2139
Location: Estonia
Madis731 14 Mar 2006, 12:32
BitTest instructions are faster on newer processor taking the same amount of microinstructions with comparable TEST,AND,OR,XOR instructions. On older processors they took tens of clocks because of the logic they followed (shift and test flags, shift and test flags....). Now on the microcode level they are assembled as TESTs, ANDs, ORs or XORs for BT, BTS, BTR, BTC respectively.
Post 14 Mar 2006, 12:32
View user's profile Send private message Visit poster's website Yahoo Messenger MSN Messenger Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8356
Location: Kraków, Poland
Tomasz Grysztar 14 Mar 2006, 13:17
BT instructions with the register operand for bit number have some advantage over TEST/AND/OR where you need to do shifts by CL etc.

Also, as it is not widely known, when you do things like
Code:
BT [EBX],EAX    

the number of bit indexed by EAX may be higher that 31, and you can index very large arrays of bits this way.
Post 14 Mar 2006, 13:17
View user's profile Send private message Visit poster's website Reply with quote
Madis731



Joined: 25 Sep 2003
Posts: 2139
Location: Estonia
Madis731 14 Mar 2006, 14:01
Code:
.code
;Is World capitalized?
  bt [sayhello],32*6+6
  je .itisnot
  ;YES it is Very Happy
.itisnot:

.data
  sayhello db 'Hello World!'
    

Does it really work? I know that this will not exactly hold true in all cases, but its only an example. Hmm, I should investigate it more.
Post 14 Mar 2006, 14:01
View user's profile Send private message Visit poster's website Yahoo Messenger MSN Messenger Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8356
Location: Kraków, Poland
Tomasz Grysztar 14 Mar 2006, 14:04
No, it won't work this way. It only works when the bit is indexed by register, like:
Code:
  mov eax,32*6+6
  bt [sayhello],eax    


Though in the case when you give the number of bit directly, the assembler could work it out and change the instruction to "BT [sayhello+6],6" - Intel manuals states that some assemblers do it (though I don't know which ones are those). However flat assembler doesn't. Do you think it should?
Post 14 Mar 2006, 14:04
View user's profile Send private message Visit poster's website Reply with quote
Madis731



Joined: 25 Sep 2003
Posts: 2139
Location: Estonia
Madis731 14 Mar 2006, 14:49
Ok, the results:
15-16 clocks per cycle on a P4:
Code:
        ;I don't know why Olly doesn't recognize pause hint!?
        ;Well it didn't help anyway Very Happy
        mov ecx,1048576
      .testbits:
        bt [403000h],ecx
        loop    .testbits
    

I managed to go as slow as 1.07 clocks per TEST/DEC ECX cycle with 16x unrolling:
Code:
        mov ecx,1048576/16
      testbits:
        bt [403000h],ecx
        dec ecx
        bt [403000h],ecx
        dec ecx
        bt [403000h],ecx
        dec ecx
        bt [403000h],ecx
        dec ecx
        bt [403000h],ecx
        dec ecx
        bt [403000h],ecx
        dec ecx
        bt [403000h],ecx
        dec ecx
        bt [403000h],ecx
        dec ecx
        bt [403000h],ecx
        dec ecx
        bt [403000h],ecx
        dec ecx
        bt [403000h],ecx
        dec ecx
        bt [403000h],ecx
        dec ecx
        bt [403000h],ecx
        dec ecx
        bt [403000h],ecx
        dec ecx
        bt [403000h],ecx
        dec ecx
        bt [403000h],ecx
        dec ecx
        jnz     testbits 
    
Post 14 Mar 2006, 14:49
View user's profile Send private message Visit poster's website Yahoo Messenger MSN Messenger Reply with quote
Reverend



Joined: 24 Aug 2004
Posts: 408
Location: Poland
Reverend 14 Mar 2006, 16:19
I didn't know that bt instrcutions are faster. But we learn all the time. Thanks for explaining me this
Post 14 Mar 2006, 16:19
View user's profile Send private message Visit poster's website Reply with quote
Borsuc



Joined: 29 Dec 2005
Posts: 2465
Location: Bucharest, Romania
Borsuc 14 Mar 2006, 17:18
Tomasz Grysztar wrote:
the number of bit indexed by EAX may be higher that 31, and you can index very large arrays of bits this way.

That's quite useful for compression algos (or where controlling individual bits is important). Sure, bsf and bsr are also needed in some cases, bt can't do it all (btw the fact that it copies into the carry flag is pretty useful, you can do tricks with rotates and adc/sbb Wink )

Tomasz Grysztar wrote:
Though in the case when you give the number of bit directly, the assembler could work it out and change the instruction to "BT [sayhello+6],6" - Intel manuals states that some assemblers do it (though I don't know which ones are those). However flat assembler doesn't. Do you think it should?

I would vote for it (or have 'advanced' optimizing macros, but it might get a bit slow with macros).
Post 14 Mar 2006, 17:18
View user's profile Send private message Reply with quote
Madis731



Joined: 25 Sep 2003
Posts: 2139
Location: Estonia
Madis731 15 Mar 2006, 08:07
Wouldn't the offset make the instructions longer ^o) and I don't know how to comment speed on that. At least my test results showed that there is no penalty in calculating offsets from say EAX=66666 Razz so I don't know what FASM should do.

I really think that if I write bt [address],one_million_in_eax, then I intend to do so. If I needed indexes, scales, offsets, I'd use LEA in combination with 32-bit test/cmp instrutions...
Post 15 Mar 2006, 08:07
View user's profile Send private message Visit poster's website Yahoo Messenger MSN Messenger Reply with quote
MazeGen



Joined: 06 Oct 2003
Posts: 977
Location: Czechoslovakia
MazeGen 15 Mar 2006, 08:51
Note that BT instructions with a memory operand are very slow on processors prior to P4.
Post 15 Mar 2006, 08:51
View user's profile Send private message Visit poster's website Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 15 Mar 2006, 14:46
Tomasz Grysztar wrote:
Intel manuals states that some assemblers do it (though I don't know which ones are those). However flat assembler doesn't. Do you think it should?
Please no, the inmediate value could be a symbol with a very high value which can cause a page fault and then it will be difficult to find out the problem (especially because you will find an address operand very different).
Post 15 Mar 2006, 14:46
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.