One of the very useful thing you can do in PowerBASIC inline assembler
is perform rotation of bits in a register by a controlled number of
bits.
The Intel instructions that will do it are respectively ROR & ROL which
is "rotate Right" and "rotate Left". One of the many useful things you
can do with rotation of bits is to retrieve smaller parts of a larger
register or alternatively load smaller data sizes into a larger register.
The concept is nearly machanically simple once you understand it and with
only a little practice, it is an easy to write and simple process that is
very hard to do any other way.
The layout of a 32 bit register needs to be understood in the way it is
writen in binary to make sense but that is simple enough to do. PowerBASIC
has the &B1111111 notation that makes it easy to read & understand. A 32
bit variable has the following form,
That is the "&B" plus 32 digits of either "0" or "1". If you loaded this 32
bit variable into the EAX register with,
then if you wanted the low BYTE value, it is already in the AL register
where if you needed the low WORD value, it is already in the AX register.
This is because different data sizes are possible with Intel processors in
the SAME register by reading the correct amount of bits from it.
With that variable loaded into the EAX register, it has the following form,
This means that you can easily get at AL, AH & AX but it leaves you with a
problem getting the values in the high word of the EAX register.
When you use bit rotation, you physically move a set number of bits either
right or left with wrap around at the ends so you can easily reposition
the piece of data you need from ther 32 bit register to where you can get
at it.
The ROL instruction works like this (slightly simplified),
The ROR instruction rotates in the reverse direction.
You can control how many bits you rotate at one time by the actual instruction
and this allows you to access parts of the 32 bit register that cannot easily
be got at other ways.
If you needed to get the high BYTE of the high WORD in the register, you can
either rotate it LEFT by 8 bits so that it wraps around into AL or you can
rotate it RIGHT by 24 bits, either will do. You then have the value u need from
the 32 bit register in the AL register and can place it where you need.
Putting the high WORD into AX is even easier, rotate it 16 bits in either direction
and you can then use,
Because PowerBASIC has both binary display as bin$ and hex display as hex$, this
is very easy to test in a visual way so it is easy to make yourself a small rotation
lab to test out rotating values to get a good feel for how it works.
It is in fact a lot easier to work in HEX once you understand what the bit rotation
is about as it takes up a lot less space and it is a lot easier to test out. The trick
when you use either hex$ or bin$ is to use the second parameter for the number of digits
to display. For 32 bit binary with bin$, use 32 as the number of digits to display and
there will be no truncation of leading zeros. With 32 bit hex for hex$, use 8 as the number
of digits.
Here is an example of putting 3 byte values into COLORREF format for RGB colours in a DWORD
size variable.
This lets you see visually where the hex bytes are put in the register. It works by
zeroing the EAX register first, loading a BYTE value into AL and rotating the EAX register
by 8 bits.
A small piece of PURE PowerBASIC for your pleasure.
[email protected]
is perform rotation of bits in a register by a controlled number of
bits.
The Intel instructions that will do it are respectively ROR & ROL which
is "rotate Right" and "rotate Left". One of the many useful things you
can do with rotation of bits is to retrieve smaller parts of a larger
register or alternatively load smaller data sizes into a larger register.
The concept is nearly machanically simple once you understand it and with
only a little practice, it is an easy to write and simple process that is
very hard to do any other way.
The layout of a 32 bit register needs to be understood in the way it is
writen in binary to make sense but that is simple enough to do. PowerBASIC
has the &B1111111 notation that makes it easy to read & understand. A 32
bit variable has the following form,
Code:
r32& = &B11111111000000001111111100000000
bit variable into the EAX register with,
Code:
! mov eax, r32&
where if you needed the low WORD value, it is already in the AX register.
This is because different data sizes are possible with Intel processors in
the SAME register by reading the correct amount of bits from it.
With that variable loaded into the EAX register, it has the following form,
Code:
AX |<---high word--->|<---low word---->| 11111111 00000000 11111111 00000000 |<------>|<------>|<------>|<------>| AH AL
problem getting the values in the high word of the EAX register.
When you use bit rotation, you physically move a set number of bits either
right or left with wrap around at the ends so you can easily reposition
the piece of data you need from ther 32 bit register to where you can get
at it.
The ROL instruction works like this (slightly simplified),
Code:
,-<-|------- bits ------|-<-, | | '----->--------------->-----'
You can control how many bits you rotate at one time by the actual instruction
and this allows you to access parts of the 32 bit register that cannot easily
be got at other ways.
If you needed to get the high BYTE of the high WORD in the register, you can
either rotate it LEFT by 8 bits so that it wraps around into AL or you can
rotate it RIGHT by 24 bits, either will do. You then have the value u need from
the 32 bit register in the AL register and can place it where you need.
Code:
! mov ByteValue, al
and you can then use,
Code:
! mov WordValue, ax
is very easy to test in a visual way so it is easy to make yourself a small rotation
lab to test out rotating values to get a good feel for how it works.
It is in fact a lot easier to work in HEX once you understand what the bit rotation
is about as it takes up a lot less space and it is a lot easier to test out. The trick
when you use either hex$ or bin$ is to use the second parameter for the number of digits
to display. For 32 bit binary with bin$, use 32 as the number of digits to display and
there will be no truncation of leading zeros. With 32 bit hex for hex$, use 8 as the number
of digits.
Here is an example of putting 3 byte values into COLORREF format for RGB colours in a DWORD
size variable.
Code:
var& = 0 red? = &HFF green? = &HDD blue? = &HAA ! xor eax, eax ; 1 zero the register ! mov al, blue? ; 1 blue value ! rol eax, 8 ; 3 ! mov al, green? ; 1 green value ! rol eax, 8 ; 3 ! mov al, red? ; 1 red value ! mov var&, eax MessageBox hWin,ByCopy hex$(var&,8),"RGB", _ %MB_OK or %MB_ICONINFORMATION
zeroing the EAX register first, loading a BYTE value into AL and rotating the EAX register
by 8 bits.
A small piece of PURE PowerBASIC for your pleasure.
[email protected]
Comment