Search code examples
cinstructions

split 32 bit instruction into bytes and move result to another address using c


i have a 32 bit instruction that i wish to split into four bytes. Let say the instruction looks like this:

yyyyyzzzzzzxxxxxx?????????

The instruction is a word that consists of four unsigned ints. y represents the operation code, and ??? are for the unused space. I am working on a big-endian machine.

What I would like to happen is to move the values from z + w to a.

I have never worked in C before but I have tried to do it like this.

Here is how I read the word, just so I ca print out each byte:

unsigned int a, b, c, o;
w = instruction << 24;
z = instruction << 16;
x = instruction << 8;
y = instruction;

Here I print unsigned values, just to check what the result are.

printf("%u\n", w);
printf("%u\n", z);
printf("%u\n", x);
printf("%u\n", y);
printf("\n");

regs[x] = instruction + instruction << 8;

if I print out the values of regs[x] after this, then I can see that I has a value now, but is this the correct way of doing it? When I do like this, do I set the register = z + w?

EDIT Mabye i should get the bits like this?

            y = (inst >> 24) & 077;
            x = (inst >> 16) & 0xffff;
            z = (inst >> 8) & 0xffff;
            w = (inst) & 0xffff;

and then do like this:

regs[y] = z + w;

Solution

  • If you like to use only bit positions and counts you can build a bit mask of i.e. 9 bits with setting the next bit and decrement (1<<10)-1. So your values are

    #define MASK(n) ((1<<(n+1))-1)
    
    unsigned int w = instruction & MASK(9);
    unsigned int x = (instruction >> 9) & MASK(6);
    unsigned int z = (instruction >> 15) & MASK(6);
    unsigned int y = (instruction >> 21) & MASK(5);
    

    all values are down shifted. So if you like to combine z and w you will have to

    unsigned int zw = z<<9 | w; 
    

    because w contains 9 bits, or

    unsigned int wz = w<<6 | z; 
    

    because z contains 6 bits.