Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What do these macros do?

Tags:

c

pic

I have inherited some heavily obfuscated and poorly written PIC code to modify. There are two macros here:

#define TopByteInt(v) (*(((unsigned char *)(&v)+1)))
#define BottomByteInt(v) (*((unsigned char *)(&v)))

Is anyone able to explain what on earth they do and what that means please?

Thanks :)

like image 839
DiBosco Avatar asked Aug 26 '14 11:08

DiBosco


People also ask

How many macros should I eat in a day?

Work out how many grams of each macro you need to eat To work out how many grams of each you need, you multiply your total daily calories by 0.4 for protein and 0.3 for carbohydrates and fat. The protein and carbohydrate figures are then divided by 4 and the fat figure by 9.

What are the three macros and what do they do for the body?

Carbohydrates, fat and protein are called macronutrients. They are the nutrients you use in the largest amounts. “Macronutrients are the nutritive components of food that the body needs for energy and to maintain the body's structure and systems,” says MD Anderson Wellness Dietitian Lindsey Wohlford.

What is a macro why are they so useful?

A macro is a set of instructions used to execute repetitive tasks. You can record a set of commands and then play them back with one or two keystrokes. That means that you can save A LOT of time when doing routine and repetitive tasks.


3 Answers

They access a 16-bit integer variable one byte at a time, allowing access to the most significant and least significant byte halves. Little-endian byte order is assumed.

Usage would be like this:

uint16_t v = 0xcafe;
const uint8_t v_high = TopByteInt(&v);
const uint8_t v_low  = BottomByteInt(&v);

The above would result in v_high being 0xca and v_low being 0xfe.

It's rather scary code, it would be cleaner to just do this arithmetically:

#define TopByteInt(v)    (((v) >> 8) & 0xff)
#define BottomByteInt(v) ((v) & 0xff)
like image 189
unwind Avatar answered Oct 02 '22 03:10

unwind


(*((unsigned char *)(&v)))

It casts the v (a 16 bit integer) into a char (8 bits), doing this you get only the bottom byte.

(*(((unsigned char *)(&v)+1)))

This is the same but it gets the address of v and sum 1 byte, so it gets only the top byte.

It'll only work as expected if v is a 16 bits integer.

like image 24
dfranca Avatar answered Oct 02 '22 04:10

dfranca


Ugg.

Assuming you are on a little-endian platform, that looks like it might meaningfully be recorded as

#define TopByteInt(v) (((v) >> 8) & 0xff)
#define BottomByteInt(v) ((v) & 0xff)

It is basically taking the variable v, and extracting the least significant byte (BottomByteInt) and the next more significant byte (TopByteInt) from that. 'TopByte' is a bit of a misnomer if v isn't a 16 bit value.

like image 36
Tom Tanner Avatar answered Oct 02 '22 04:10

Tom Tanner