Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 895 Vote(s) - 3.49 Average
  • 1
  • 2
  • 3
  • 4
  • 5
cutting bits in C++

#1
Suppose we have a binary file, that contains 32 bit numbers. Each 32bit number represents an instruction. My question: is it possible to cut this bits into chunks of 6+5+5+16 directly. Something like:

typedef struct _instruction
{
int op_code : 6;
int reg_dest : 5;
int reg_s1 : 5;
int offset : 16;
} INST, *PINST;

int read_32_bits = read_next_instr();

INST i = (INST)read_32_bit; /* this would cut the bits into chunks*/



Reply

#2
You can just cast your struct as a pointer to the address of your 32-bit data.

INST* i = (INST*)&read_32_bit;

Then you could access your fields, like this:

printf("opcode = %x", i->op_code);
Reply

#3
Why not create a bit structure like you have but then place it inside a union? I dropped the typedef so it uses C++ style definitions.

struct instruction
{
int op_code : 6;
int reg_dest : 5;
int reg_s1 : 5;
int offset :16;
};

union INST
{
instruction a;
uint32_t b;
};

You could store/load the 32-bit values using network functions:

INST i;
i.b = ntohl(value);

And now you can reference the bit fields without typecasting.

if (i.a.op_code == XXX)
Reply

#4
Here is an answer that will work, be portable, not invoke undefined behavior on any compiler, and be optimized fairly effectively:

struct instruction {
typedef unsigned int uint_t;

explicit instruction(uint_t val) : val_(val) {}
instruction(uint_t op_code, uint_t reg_dest, uint_t reg_s1, uint_t offset)
: val_((op_code & 0x3fu << 26) | (reg_dest & 0x1fu << 21) |
(reg_s1 & 0x1fu << 16) | (offset & 0xffffu))
{
}

uint_t op_code() const { return (val_ >> 26) & 0x3fu; }
void op_code(uint_t newval) { val_ = (newval & 0x3fu << 26) | (val_ & 0x3ffffffu); }

uint_t reg_dest() const { return (val_ >> 21) & 0x1fu; }
void reg_dest(uint_t newval) { val_ = (newval & 0x1fu << 21) | (val_ & 0xfc1fffffu); }

uint_t reg_s1() const { return (val_ >> 16) & 0x1fu; }
void reg_s1(uint_t newval) { val_ = (newval & 0x1fu) << 16) | (val_ & 0xffe0ffffu); }

uint_t offset() const { return (val_ >> 16) & 0xffffu; }
void offset(uint_t newval) const { val_ = (newval & 0xffffu) | (val & 0xffff0000u); }

uint_t &int_ref() { return val_; }
uint_t int_ref() const { return val_; }

private:
uint_t val_;
};

This lets you access all of the bitfields with a very convenient notation. I think it's also a POD, which lets you use it in a few interesting ways. And a good compiler will do a fairly decent job of optimizing the bit munging operations, especially if you have several calls to the convenience functions in a row.

It's almost as nice as having an overlay bit field. It's just a bit more work to define in the first place.

Also, I changed the type to `unsigned int` because if you're fiddling around with the bits, you really want a simply represented number without a sign bit or anything funky like that. Ideally you'd be including the `<cstdint>` header and using `::std::uint32_t` or something in the typedef at the top.
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through