Here are two macros for using bitfields defined through RECORD. Usage:
FieldSet MyRec.SlotHigh, 11
print str$(FieldGet(MyRec.SlotHigh))
FieldGet MACRO SrcDotField ; trashes and returns eax
LOCAL is, src, field
is INSTR <SrcDotField>, <.>
if is eq 0
.err <*** source.field required ***>
endif
src SUBSTR <SrcDotField>, 1, is-1
field SUBSTR <SrcDotField>, is+1
ifdifi src, <eax>
mov eax, src
endif
and eax, mask field
if field
shr eax, field
endif
EXITM <eax>
ENDM
FieldSet MACRO SrcDotField, TheVal ; trashes and returns eax
LOCAL is, src, field
is INSTR <SrcDotField>, <.>
if is eq 0
.err <*** source.field required ***>
endif
src SUBSTR <SrcDotField>, 1, is-1
field SUBSTR <SrcDotField>, is+1
ifdifi <TheVal>, <eax>
mov eax, TheVal
endif
if field
shl eax, field
endif
and src, not mask field
add src, eax
ENDM
Examples:
MyRECORD RECORD SlotHigh:4, SlotMid:7, SlotLow:7, SlotRest:32-4-2*7 ; the order is high to low
.data
MyRec1 MyRECORD <1, 3, 7, 15>
.data?
MyRec MyRECORD <>
...
Print Str$("The value of MyRec1.SlotMid is\t%i\n", FieldGet(MyRec1.SlotMid))
Print Str$("The value of MyRec1.SlotLow is\t%i\n", FieldGet(MyRec1.SlotLow))
FieldSet MyRec.SlotHigh, 11
FieldSet MyRec.SlotMid, 12
FieldSet MyRec.SlotLow, 13
FieldSet MyRec.SlotRest, 14
Print Str$("The value of MyRec.SlotHigh is\t%i\n", FieldGet(MyRec.SlotHigh))
Print Str$("The value of MyRec.SlotMid is\t%i\n", FieldGet(MyRec.SlotMid))
Print Str$("The value of MyRec.SlotLow is\t%i\n", FieldGet(MyRec.SlotLow))
Print Str$("The value of MyRec.SlotRest is\t%i\n", FieldGet(MyRec.SlotRest))
For compact display, I have used the Print and Str$ macros from the MasmBasic library, but the FieldSet/FieldGet macros will work with standard Masm32, too.