Hi
stevieb!
Yes, the generic set of HLL operations to set a field of bits is to do
a bit-wise AND with a one's complement of a "mask" to make sure the
bits are all unset, then do a bit-wise OR operation to set those bits
to however you want them.
The difference between the HLL version and an actual Assembly
language implementation is that there is some uncertainty in
how big a "natural integer" is with the HLL. With assembly,
I know exactly whether I've got 8, 16, 32, or 64 bits. Typically
with HLL, you only know something like size >= 32 bits for an int.
So, with ASM, the "negate the MASK" step would not be there.
The ~MASK value would have been compiled in as a "load
immediate" constant. With HLL, we want to actually calculate
this "flipping of bits" mask. When we calculate ~0x3, we get
2 bits of zeroes and as as many leading one bits as needed to
make up the "native int". Design for a min size int, but allow
bigger ints.
Here is some code with a couple of things I like to do:
use strict;
use warnings;
use constant {UP => 0x0<<3,
DOWN => 0x1<<3,
LEFT => 0x3<<3,
RIGHT => 0x2<<3,
MASK => 0x3<<3};
printf "direction Mask: ";
print8bits (MASK); #Prints: direction Mask: 0001 1000
my $register8b=0;
#set direction left
$register8b = $register8b & ~MASK | LEFT;
print8bits ($register8b); #Prints: 0001 1000
#set direction down
$register8b = $register8b & ~MASK | DOWN;
print8bits ($register8b); #Prints: 0000 1000
sub print8bits
{
my $int = shift;
print map{s/(\d{4})/$1 /g;$_;}sprintf "%08b\n", $int;
}
- Consider the use of the constant feature. Make a
constant block for each of the fields in the 16 bit register.
Naming convention to your satisfation. Maybe DIRECT_UP or DIRECTION_UP instead
of just UP or whatever. Consider the naming convention in whatever
documentation that you are working from.
- I prefer "0x3" notation over just decimal 3 for these things. Although
they code to exactly the same bits, use of 0x notation alerts me
to the fact that this is some hardware bit thing and not a "normal"
variable.
- For debugging, I find something like my sub print8bits() to be useful.
Space the bits out into 4 bit hex compatible groups. The %b format
spec in Perl is very nice (doesn't exist in std C.. have to "roll your own").
- Consider a naming convention to indicate how many of the bits
are "significant". $register8bit , $r8bit_control or whatever. Design
the code that it will still work with native int sizes greater than
what current platform is.
- While manipulating the 16 or 8 bit register, I just keep the
internal representation as a native int, whatever that size is, rather
than splitting this into say $lsB and $msB like you did. Or mucking around
prematurely with pack/unpack.
BTW, your code could confuse a hardware guy. Use lower case "b" for
bit and upper case "B" for byte, e.g. $msB instead of $msb.
- If you do a lot of bit twiddling, you will find that the inability
to access the hardware carry bit is a real hassle. There are various
techniques around that, but not in the scope of this post.
Hope this helps.
I have written most of my bit fiddling code in C as I am emulating say
a hardware ECC algorithm or whatever and sometimes "fast" is important. But Perl can do bit manipulation
amazingly well and I
have used Perl to decode some complex binary formats.
Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
Read Where should I post X? if you're not absolutely sure you're posting in the right place.
Please read these before you post! —
Posts may use any of the Perl Monks Approved HTML tags:
- a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
| |
For: |
|
Use: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.