Skip to main content
GameDev.net gamedev.net
🔒 Locked

How are 16bit values treated when looked at as separate bytes?

Started by nolongerhere Feb 9, 2009 at 10:36 PM 7 replies 1.5k views
Original Post
nolongerhere
nolongerhere
Ive been trying to learn more about assembly lately and I ran into something I was curious about. Im used to C++ so I will talk about it in those terms. Lets say I have an array of unsigned chars (each a byte). But I wanted to figure out what 16bit value two of the chars would make? Do I like, shift the first byte into a 16bit int then shift the second byte into it, thus giving me the 16bit value??? I hope you guys understand what im asking! Thanks
outRider
outRider
Look up endianness.
nolongerhere
nolongerhere
Thanks, it seems to fit the bill but im still not exactly sure how I go about actually splitting/joining the two bytes in C++ code. Perhaps someone can show me an example of how to join two bytes into a single 16bit value and then back into its two 8bit equilalent?
NerdInHisShoe
NerdInHisShoe
Suppose you have a 16-bit value:

unsigned short x = 0xabcd;


You can cast it to an array of chars (8-bits each)

char *ptr = (char *)&x


Then you can access the individual bytes by dereferencing the character array (watch for endianness)

The other way also works, a byte array can be cast to an array of shorts or ints:

char x[8];unsigned short *ptr = (unsigned short *)x;


You can also assemble a multi-byte value from different bytes:

char x = 0xab;char y = 0xcd;unsigned short z;z = (x << 8) | y;   //z holds 0xabcd
Johnny was a chemist's son by Johnny is no more, for what Johnny thought was H2O was HO4
nolongerhere
nolongerhere
Quote:
Original post by NerdInHisShoe
Suppose you have a 16-bit value:

unsigned short x = 0xabcd;


You can cast it to an array of chars (8-bits each)

char *ptr = (char *)&x


Then you can access the individual bytes by dereferencing the character array (watch for endianness)

The other way also works, a byte array can be cast to an array of shorts or ints:

char x[8];unsigned short *ptr = (unsigned short *)x;


You can also assemble a multi-byte value from different bytes:

char x = 0xab;char y = 0xcd;unsigned short z;z = (x << 8) | y;   //z holds 0xabcd


Wow thanks NerdInHisShoe! Very helpful. In your last example, of assembling a multi-byte value from two bytes, how would I disassemble it in this manner?
Wolfdog
Wolfdog
y = z & 0xff;x = (z >> 8) & 0xff;


edit: but you need to be using unsigned char for that to work correctly.
nolongerhere
nolongerhere
Quote:
Original post by Wolfdog
y = z & 0xff;x = (z >> 8) & 0xff;


edit: but you need to be using unsigned char for that to work correctly.


I am. Thanks very much Wolfdog and everyone else!
phresnel
phresnel
Quote:
Original post by NerdInHisShoe
array of chars (8-bits each)


It is interesting to note at this point that a byte in C++ is not always 8bits, it is just at least 8 bits in size. The funny thing is, a char is always and always exactly one byte long. But a "c++-byte" might have different bit-sizes on different machines. Have a look at this article for more details: Parashift [26.1-26.6].
Vortez
Vortez
Quote:
Original post by Wolfdog
y = z & 0xff;
x = (z >> 8) & 0xff;


Why not do:

BYTE y = z & 0x00ff;
BYTE x = z >> 8;

Since z is 2 bytes length, and in x = (z >> 8) & 0xff;, the 0xff isn't necessary, and he sould use 0x00ff cause like i said, z is 2 byte, but in this case it would work.

Just trowing my 10 cent in the pot...

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.