How to mirror a byte

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

How to mirror a byte

跳至解决方案
7,117 次查看
pelle2005reg
Contributor I

Hi to all,

i would like to say if in the HCS12 assembler there is a instruction to mirror a byte.

That is, "convert" a byte in his mirror, for example:
$01 --> $80

$A1 --> $85

 

An istruction o a set of instruction (the fatest) .

Thank you

标签 (1)
0 项奖励
回复
1 解答
3,109 次查看
CompilerGuru
NXP Employee
NXP Employee

The fastest way is probably a table lookup if you can afford the memory for a 256 bytes table.

 

Daniel

在原帖中查看解决方案

0 项奖励
回复
6 回复数
3,110 次查看
CompilerGuru
NXP Employee
NXP Employee

The fastest way is probably a table lookup if you can afford the memory for a 256 bytes table.

 

Daniel

0 项奖励
回复
3,109 次查看
pelle2005reg
Contributor I
The table solution was also my first idea.
0 项奖励
回复
3,109 次查看
bigmac
Specialist III

Hello,

 

If my estimations are correct, the byte table lookup method should occupy about 7 cycles.  The nybble table lookup method would seem much less efficient at about 30 cycles (using assembly code, rather than C).  This would compare with the "shift loop" method at about 44 cycles.  I assumed that ACCB contained the byte value to be mirrored, and that the result was also in ACCB.

 

The byte table lookup code might consist of the following:

   ldx   #BYTETAB   ; Start of byte table

   abx

   ldab  0,x

 

Regards,

Mac

 

0 项奖励
回复
3,109 次查看
kef
Specialist I

Mac,

 

HC12 indexed addressing allows LDAB  B,X  , so -2 cycles saved on ABX.

Also loop unrolling should be considered. With single cycle shift instructions RORB, ROLA, or similar, reversing bits order from B to A should take 2cycles per bit, 2*8=16 cycles. + 1 cycle to transfer result back from A to B.

 

0 项奖励
回复
3,109 次查看
Lundin
Senior Contributor IV
This C code is fairly effective too. It works on nibble-level instead of byte-level, to save ROM:

#pragma CONST_SEG GLOBAL_ROM

static const uint8 MIRROR_TABLE[16] =
{
  0x0, 0x8, 0x4, 0xC,  /*  0-3  */
  0x2, 0xA, 0x6, 0xE,  /*  4-7  */
  0x1, 0x9, 0x5, 0xD,  /*  8-11 */
  0x3, 0xB, 0x7, 0xF   /* 12-15 */
};

#pragma CONST_SEG DEFAULT


uint8 my_byte; /* byte to mirror */
uint8 tmp;

tmp = MIRROR_TABLE[my_byte >> 4];
tmp <<= 4;
my_byte = MIRROR_TABLE[my_byte & 0x0F] | tmp;


On a Freescale micro, the left shift will be optimized into a MUL instruction, saving a few ticks. The right shift will become 4 LSRx instructions (no optimization possible).

If you expand the lookup table from 16 bytes to 256 bytes you don't need to do the shifting and thus save 10 CPU ticks or so, at the cost of ROM.
Message Edited by Lundin on 2009-12-01 11:46 AM
0 项奖励
回复
3,109 次查看
AndersJ
Contributor IV

The C code to mirror a byte may be fairly effective, but unfortunately it doesn't work.

It basically does what it should but swaps the output nibbles.

 

Try this  instead:

tmp = MIRROR_TABLE[my_byte & 0x0F];
tmp <<= 4;
my_byte = MIRROR_TABLE[my_byte >> 4]; | tmp;

 

Anders Johansson

0 项奖励
回复