You could try a lookup table approach:
static const char LUT[][] = { // index like this LUT[bot][top]
//top: 0 1 2 3 4 5 6 7 8
0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF, // bot: 0
0x00, 0x00, 0x02, 0x06, 0x0E, 0x1E, 0x3E, 0x7E, 0xFE, // bot: 1
0x00, 0x00, 0x00, 0x04, 0x0C, 0x1C, 0x3C, 0x7C, 0xFC, // bot: 2
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x78, 0xF8, // bot: 3
0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x30, 0x70, 0xF0, // bot: 4
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x60, 0xE0, // bot: 5
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xC0, // bot: 6
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, // bot: 7
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // bot: 8
};
char mask = LUT[bot][top];
Also: If for whatever reason you go with bit manipulation this solution requires less ops. In addition a superscalar processor should evaluate the left and right side of the xor in parallel.
char mask = (0xFF << top) ^ (0xFF << bot);