I know how to define this to masm
typedef struct MYSTRUCT
{
struct {
DWORD Flags:12,
DWORD Size:4,
DWORD Max:16
}
DWORD CodeSize;
} MYSTRUCT;
But how do I define this to masm
typedef struct MYSTRUCT
{
unsigned Flags:12;
unsigned Size:4;
unsigned Max:16;
DWORD CodeSize;
} MYSTRUCT;
Does anyone know how to do this?
Edit: First example was wrong
You can use RECORDs for this:
MYSTRUCT struct
xyz RECORD Max:16,_Size:4,Flags:12
codeSize DWORD ?
MYSTRUCT ends
However, the problem is, that you can't reuse the names Max, _Size and Flags for further bit field definitions...
It is probably better to declare the bit field as a DWORD and use EQUs for masking the bits.
Thanks for your answer.
I have tryed that. It is compiled OK but not
mov MYSTRUCT.xyz,101111111110000000001111100000b
mov MYSTRUCT.xyz,-1
it returns "error A2006: undefined symbol"
This is OK as I did for the first example
xyz RECORD Max:16,_Size:4,Flags:12
MYSTRUCT struct
_xyz xyz <>
codeSize DWORD ?
MYSTRUCT ends
mov MYSTRUCT._xyz,101111111110000000001111100000b
mov MYSTRUCT._xyz,-1
How do I use EQUs for masking the bits?
And how do I define this structure
typedef struct MYSTRUCT
{
CorExceptionFlag Flags:16;
unsigned TryOffset:16;
unsigned TryLength:8;
unsigned HandlerOffset:16;
unsigned HandlerLength:8;
union {
DWORD ClassToken;
DWORD FilterOffset;
};
} MYSTRUCT;
Quote from: minor28 on September 26, 2011, 07:38:33 AM
Thanks for your answer.
I have tryed that. It is compiled OK but not
mov MYSTRUCT.xyz,101111111110000000001111100000b
mov MYSTRUCT.xyz,-1
it returns "error A2006: undefined symbol"
Not sure, but it looks as if you used the STRUCT name (MYSTRUCT) instead of the name you used to
declare the structure; you do know the difference between defining and declaring something, right?
In any case, please please please please
please don't use ugly expressions like "101111111110000000001111100000b" in your code! Let me explain one way to handle this (not the only way, but I think a good one):
If you're going to use binary numbers to define a field, flag or variable, then do it ONCE only in an EQU:
$xyzValue EQU 101111111110000000001111100000b
(I like to prefix all my equates with "$" to distinguish them from variables)
Then you can set your variable thus:
MOV struc.xyz, $xyzValue
See how neat that is?
As someone else said, bit fields are best set up using EQUs instead of using MASM's RECORD operator. (I've never used it.) And I've really only used bit fields for single-bit flags. Those are easy to set up and use with equates:
$flagRed EQU 1
$flagGreen EQU 2
$flagTorn EQU 4
$flagRipped EQU 8
$flagSad EQU 10H
$flagHappy EQU 20H
$flagBroke EQU 40H
$flagRich EQU 80H
Flag DW ?
...
; Initialize the flag variable by zeroing it:
XOR AX, AX
MOV Flag, AX
; Now set a flag bit in it:
OR Flag, $flagRed
; Maybe set another flag (doesn't affect any other flags):
OR Flag, $flagRipped
; Later, test the variable for a certain bit:
TEST Flag, $flagRich ;Is the bit set?
JNZ got_money ;Yes, go somewhere
Notice I like to use hexadecimal bit assignments (1, 2, 4, 8, 10, 20, 40, 80, 100, 200, etc.). But if you prefer binary, that's fine too. Whatever works for you.
Record is the badest define that can be found in masm.
Field bits have there names global to the source code instead of local as in a structure.
The total names lenght is limited inside the record.
records allow you to use bit mask ,that all.
More usable is this form of declare:
Quote
cpu_rflags_CF equ 1 SHL 0
cpu_rflags_PF equ 1 SHL 2
cpu_rflags_AF equ 1 SHL 4
cpu_rflags_ZF equ 1 SHL 6
cpu_rflags_SF equ 1 SHL 7
cpu_rflags_TF equ 1 SHL 8
cpu_rflags_IF equ 1 SHL 9
cpu_rflags_DF equ 1 SHL 10
cpu_rflags_OF equ 1 SHL 11
cpu_rflags_IOPL equ 11b SHL 12
cpu_rflags_NT equ 1 SHL 14
cpu_rflags_RF equ 1 SHL 16
cpu_rflags_VM equ 1 SHL 17
cpu_rflags_AC equ 1 SHL 18
cpu_rflags_VIF equ 1 SHL 19
cpu_rflags_VIP equ 1 SHL 20
cpu_rflags_D equ 1 SHL 21
usage:
and eax,cpu_rflags_RF ;and you have the bit 16 ,no need to remember how the mask directive work
Records are indeed nasty animals, but here is a simpler version using the attached SetField and GetField macros.
Quoteinclude \masm32\include\masm32rt.inc
include MasmBasic_Record_Macros.inc ; extract from MasmBasic (http://www.masm32.com/board/index.php?topic=12460)
MyRecord RECORD Slot4:4, Slot7:7, Slot9:9 ; define record fields by name and # of bits
.data?
MyRec MyRecord <> ; define an empty 32-bit record with 3 fields
.code
start:
SetField MyRec.Slot4, 5 ; set 2 of 4 bits (5=0101b)
SetField MyRec.Slot4, 8 ; set bit 3, too - result should be 13
print "The content of MyRec.Slot4 is ", 9
print str$(GetField(MyRec.Slot4)), 13, 10
SetField MyRec.Slot4, 7 ; set 3 of 4 bits (7=0111b)
SetField MyRec.Slot4, 8, clear ; set bit 3, clear the others - result should be 8
print "The content of MyRec.Slot4 is ", 9
print str$(GetField(MyRec.Slot4)), 13, 10
mov eax, 111
SetField MyRec.Slot7, eax ; 7 bits aka 127 available, so 111 should be fine
SetField MyRec.Slot9, -1 ; -1 means set all 9 bits
print "The content of MyRec.Slot7 is ", 9
print str$(GetField(MyRec.Slot7)), 13, 10
print "The content of MyRec.Slot9 is ", 9
mov ecx, GetField(MyRec.Slot9)
print str$(ecx), 13, 10
SetField MyRec.Slot9, 123, clear ; set to 123, clear other bits before
print "The content of MyRec.Slot9 is ", 9
print str$(GetField(MyRec.Slot9)), 13, 10
inkey "-- press any key --"
exit
end start
Output:
The content of MyRec.Slot4 is 13
The content of MyRec.Slot4 is 8
The content of MyRec.Slot7 is 111
The content of MyRec.Slot9 is 511
The content of MyRec.Slot9 is 123
jj, I must admit, that's some pretty nifty stuff, especially that whole MasmBasic thing you created. (I'll probably never use it myself, but it's still impressive.)
I'm just wondering, though: who on earth would really want to use bit fields in an actual program? Thinking back, the only time I've ever used them was to unpack the old DOS date/time structures--remember those? Even then, I never used the assembler, but just defined my own EQUs and did the necessary shifting and masking by hand.
Unless they have some use in reading bitmaps or something, I can't think of a problem that they'd be a good solution for.
Nice to know they're there just in case, though.
Yeah, I admit SetField is probably the most useless function in MasmBasic... it was just the intellectual challenge to find something simpler than MASM's handling of RECORDs :bg
> I'll probably never use it myself
Remember you can use it in parallel:
include \masm32\MasmBasic\MasmBasic.inc
; include \masm32\include\masm32rt.inc
Especially the deb macro is in most cases a much better alternative for bug chasing than OllyDbg. I use deb 4 (=to console) and deb 5 (=to logfile) for developing all the time, it saves me many hours of work. Or, another example, deb 6 and higher writes to console inside a loop for the first n iterations:
Quoteinclude \masm32\MasmBasic\MasmBasic.inc
Init
xor ecx, ecx
mov eax, -100
.Repeat
deb 6, "Looping", ecx, eax ; print ecx & eax to console for the first 6 iterations of the loop
inc ecx
mul ecx
.Until ecx>1000000
Inkey "bye"
Exit
end start
Output:
Looping
ecx 1
eax -100
Looping
ecx 2
eax -200
...
Looping
ecx 6
eax -72000
bye
EDIT: Just realised that deb
6 and higher (the one that does
n loops and then stops) skipped the first loop. It's called a bug :red
Version MasmBasic6October2011b.zip (here (http://www.masm32.com/board/index.php?topic=12460.0)) is ok.
extracting bit field with the declare i posted,for example:
Quote
cpu_rflags_IOPL equ 11b SHL 12
and eax,cpu_rflags_IOPL
shr eax,12 ;Why 12 ??? it's a difficult question :bdg
Quote from: minor28 on September 26, 2011, 07:38:33 AM
Thanks for your answer.
I have tryed that. It is compiled OK but not
mov MYSTRUCT.xyz,101111111110000000001111100000b
mov MYSTRUCT.xyz,-1
it returns "error A2006: undefined symbol"
http://www.masm32.com/board/index.php?topic=13386.msg104286#msg104286
Use "mask, and, or, shl, shr". If you think C/C++ does it without "and, or, shl, shr" - think/disassemble again.
Quote from: minor28 on September 26, 2011, 07:38:33 AM
And how do I define this structure
h2incx CorHdr.h