There are 10 kinds of people in the world
If, like many embedded software developers, you need to work “close to the hardware”, you will want to be able to visualize the bit patterns that map on to CPU and peripheral registers. The obvious way to do this is in binary, as you can see the 1s and 0s directly. However, I do not think that I have ever seen the option, even in assembly language, to include binary constants in software. Do feel free to comment or email me if you know of examples.
When I started out with real-time programming, after I got through my Fortran phase, I worked on DEC minicomputers. As these machines originally had word sizes like 12 and 18 bits, grouping the bits into 3s and expressing values in octal was normal. A PDP-8, for example, was a “real” computer – i.e. it had a line of lights and switches on the front; the switches were grouped into 3s for mapping onto octal values. I was always comfortable with octal and could “see” the bit patterns quite intuitively.
Later on, a PDP-11 had 16 bit words, but DEC still insisted on using octal, which was rather odd – the left-most digit could only be 0 or 1. But the instruction set had 3-bit fields, which made some sense. In due course, with VAX machines, which had a 32-bit architecture, DEC gave in and started using hexadecimal like everyone else.
But I have never really quite felt at home with hex. Seeing “0x0C” does not immediately translate to “00001100” in my mind. So, for C/C++ code I wanted to fix this problem. All I need is my “binary.h” file, which contains 256 lines like this:
#define b00000000 ((unsigned char) 0x00)
#define b00000001 ((unsigned char) 0x01)
#define b00000010 ((unsigned char) 0x02)
…
This seems to do the job. If you would find this useful and would like a copy of the binary.h file, please email me.
It’s an old and rather geeky joke, but I like it:
There are 10 kinds of people in the world: those who understand binary and those who do not.
Sorry.
While I am on the subject of programming, you might be interested to attend a Webinar we are running on Thursday, which looks at compilers and embedded coding generally. A recording will be available after the live event.
Comments
Leave a Reply
You must be logged in to post a comment.
You are doing work that the compiler could do for you. Want a constant with bits 3, 5, and 17 set? Write 1 << 3 | 1 << 5 | 1 << 17. You get the idea.
Konrad:
You are correct, I could do it that way – a compiler would certainly resolve that expression. But which is most readable and immediately understandable: “1 << 3 | 1 << 5 | 1 << 6” or “b01101000” ?
here is a portable and compile-time calculated way to express binary constants in C. the credit is from Tom Torfs.
http://groups.google.com/group/comp.arch.embedded/msg/9d430b6d3da12c8f
and
http://cprog.tomsweb.net/binconst.txt
Thanks Victor. That’s an elegant approach, but I actually prefer the simplicity of mine [which can easily be extended to 16/32 bits]. Nice to have a choice.
One problem with your binary.h is that the constants contain a cast and therefore cannot be used in #if preprocessor directive. Code like:
#if DATAMODE == b01101000
/* Do something */
#else
#error Unsupported datamode
#endif
produces diagnostic “missing binary operator before token char” in GCC (surely confusing message for beginner programmers).
Intel’s PL/M allows binary constants (as well as octal, decimal and hex), and supports “$” as a “do nothing” separator. e.g.
1101$0110B
There’s the other joke: “Why do programmers get Halloween and Christmas confused?
Because OCT31 = DEC25”
Good point Ed. Of course PL/M was probably the only language ever designed specifically for embedded programming. I do like that joke – thanks.