Dan
Dan

Reputation: 512

Embedded C: what does var = 0xFF; do?

I'm working with embedded C for the first time. Although my C is rusty, I can read the code but I don't really have a grasp on why certain lines are the way the are. For example, I want to know if a variable is true or false and send it back to another application. Rather than setting the variable to 1 or 0, the original implementor chose 0xFF.

Is he trying to set it to an address space? or else why set a boolean variable to be 255?

Upvotes: 19

Views: 67808

Answers (9)

Peter Kühne
Peter Kühne

Reputation: 3274

0xFF sets all the bits in a char.

The original implementer probably decided that the standard 0 and 1 wasn't good enough and decided that if all bits off is false then all bits on is true.

That works because in C any value other than 0 is true. Though this will set all bytes in a char, it will also work for any other variable type, since any one bit being set in a variable makes it true.

Upvotes: 30

Olof Forshell
Olof Forshell

Reputation: 3274

These young guys, what do they know?

In one of the original embedded languages - PL/M (-51 yes as in 8051, -85, -86, -286, -386) - there was no difference between logical operators (!, &&, || in C) and bitwise (~, &, |, ^). Instead PL/M has NOT, AND, OR and XOR taking care of both categories. Are we better off with two categories? I'm not so sure. I miss the logical ^^ operator (xor) in C, though. Still, I guess it would be possible to construct programs in C without having to involve the logical category.

In PL/M False is defined as 0. Booleans are usually represented in byte variables. True is defined as NOT False which will give you 0ffh (PL/M-ese for C's 0xff).

To see how the conversion of the status flag carry took place defore being stored in a byte (boolean wasn't available as a type) variable, PL/M could use the assembly instruction "sbb al,al" before storing. If carry was set al would contain 0ff, if it wasn't it would contain 0h. If the opposite value was required, PL/M would insert a "cmc" before the sbb or append a "not al" after (actually xor - one or the other).

So the 0xff for TRUE is a direct compatibility port from PL/M. Necessary? Probably not, unless you're unsure of your skills (in C) AND playing it super safe.

As I would have.

PL/M-80 (used for the 8080, 8085 and Z80) did not have support for integers or floats, and I suspect it was the same for PL/M-51. PL/M-86 (used for the 8086, 8088, 80188 and 80186) added integers, single precision floating point, segment:offset pointers and the standard memory models small, medium, compact and large. For those so inclined there were special directives to create do-it-yourself hybrid memory models. Microsoft's huge memory model was equivalent to intel's large. MS also sported tiny, small, compact, medium and large models.

Upvotes: 9

Vaibhav Garg
Vaibhav Garg

Reputation: 737

Also adding 1 to 0xff sets it to 0( assuming unsigned char) and the checking might have been in a loop with an increment to break.

Upvotes: 2

Dan Lenski
Dan Lenski

Reputation: 79782

Here's a likely reason: 0xff is the binary complement of 0. It may be that on your embedded architecture, storing 0xff into a variable is more efficient than storing, say, 1 which might require extra instructions or a constant stored in memory.

Or perhaps the most efficient way to check the "truth value" of a register in your architecture is with a "check bit set" instruction. With 0xff as the TRUE value, it doesn't matter which bit gets checked... they're all set.

The above is just speculation, of course, without knowing what kind of embedded processor you're using. 8-bit, 16-bit, 32-bit? PIC, AVR, ARM, x86???

(As others have pointed out, any integer value other than zero is considered TRUE for the purposes of boolean expressions in C.)

Upvotes: 1

XPav
XPav

Reputation: 1170

What's really important to know about this question is the type of "var". You say "boolean", but is that a C++/C99's bool, or is it (highly likely, being an embedded C app), something of a completely different type that's being used as a boolean?

Upvotes: 3

humble_guru
humble_guru

Reputation: 526

Often in embedded systems there is one programmer who writes all the code and his/her idiosyncrasies are throughout the source. Many embedded programmers were HW engineers and had to get a system running as best they could. There was no requirement nor concept of "portability". Another consideration in embedded systems is the compiler is specific for the CPU HW. Refer to the ISA for this CPU and check all uses of the "boolean".

Upvotes: 4

mfx
mfx

Reputation: 7398

If you are in desperate need of memory, you might want to store 8 booleans in one byte (or 32 in a long, or whatever)

This can easily be done by using a flag mask:

  // FLAGMASK = ..1<<n for n in 0..7...
  FLAGMASK = 0x10;    // e.g. n=4

  flags &= ~FLAGMASK; // clear bit
  flags |= FLAGMASK;  // set bit
  flags ^= FLAGMASK;  // flip bit
  flags = (flags & ~FLAGMASK) | (booleanFunction() & FLAGMASK); // clear, then maybe set

this only works when booleanFunction() returns 0 (all bits clear) or -1 (all bits set).

Upvotes: 12

Paul Tomblin
Paul Tomblin

Reputation: 182802

As others have said, it's setting all the bits to 1. And since this is embedded C, you might be storing this into a register where each bit is important for something, so you want to set them all to 1. I know I did similar when writing in assembler.

Upvotes: 3

Cade Roux
Cade Roux

Reputation: 89711

0xFF is the hex representation of ~0 (i.e. 11111111)

In, for example, VB and Access, -1 is used as True.

Upvotes: 9

Related Questions