Ney André de Mello Zunino wrote:
Hello.
I have been having some trouble dealing with bit fields. The following
is a simple program that demonstrates it.
#include <iomanip>
#include <iostream>
struct instrucao_i
{
unsigned short opcode: 6;
unsigned short rs: 5;
unsigned short rt: 5;
unsigned short immediate: 16;
};
int main()
{
instrucao_i i = { 0x24110064 };
std::cout << std::hex;
std::cout << "opcode: " << i.opcode << '\n';
std::cout << " rs: " << i.rs << '\n';
std::cout << " rt: " << i.rt << '\n';
std::cout << "immed.: " << i.immediate << '\n';
}
Here is the binary representation of the 32-bit word being used to
initialize /i/:
0010 0100 0001 0001 0000 0000 0110 0100
Since the /opcode/ field is 6 bits long, it should be equal to the first
6 bits of /i/, i.e., 001001, which is 9 in decimal. However, this is the
output I get with both VC++ 7.1 and BCC32 5.5.1 on Windows:
D:\Temp>teste
opcode: 24
rs: 0
rt: 0
immed.: 0
Could anybody shed some light on this subject?
Thank you very much,
I believe that you should try a different approach.
Use the bitwise arithmetic operators to isolate the
bit fields into integral variables:
class Instruction
{
public:
Instruction(unsigned long data = 0);
private:
unsigned int opcode;
unsigned int rs;
unsigned int rt;
unsigned int immediate;
};
Instruction::Instruction(unsigned long data)
{
immediate = static_cast<unsigned int>(data & 0xFF);
data >>= 16;
rt = static_cast<unsigned int>(data & 0x1F);
data >>= 5;
rs = static_cast<unsigned int>(data & 0x1F);
data >>= 5;
opcode = static_cast<unsigned int>(data & 0x3F);
}
Not using bit fields allows for easier conversion from
Big Endian or Little Endian byte ordering. Also, some
compilers mess up when accessing bitfields in
structures, especially when the optimization level
is set high.
Another nice feature is that bit fields are converted
into the processor's native integral format. This
will simplify your program and make it more efficient
(faster).
You _may_ want to consider a hierarchial approach, in
which Instruction is a base class and have separate
leaf classes for each instruction. This will allow
generic functions, such as execute and print, to
be applied to any instruction. I used an array of
pointers to the Instruction base class to represent
a program.
--
Thomas Matthews
C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq:
http://www.parashift.com/c++-faq-lite
C Faq:
http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.comeaucomputing.com/learn/faq/
Other sites:
http://www.josuttis.com -- C++ STL Library book