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; }
  1. 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.
  2. 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.
  3. 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").
  4. 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.
  5. 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.
  6. 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.

In reply to Re^2: Modifying multiple bits in a byte - bitwise operators by Marshall
in thread Modifying multiple bits in a byte - bitwise operators by stevieb

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • 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:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.