cc89opcodevm-implementation

How to fix: OP-code isn't read out correctly


I'm currently trying to write a Ninja VM, a task which was given to me as an exercise. Opcode and value are saved in a 32-Bit unsigned int, with the first 8 bit being the opcode and the rest being the value. To deal with a negative value, I use a macro given to me with the exercise

#define SIGN_EXTEND(i) ((i) & 0x00800000 ? (i) | 0xFF000000 : (i))

However, when trying to retrieve the op-code of

unsigned int i = (PUSHC << 24) | SIGN_EXTEND(-2); (where PUSHC equals 1)

by using a bit-wise AND as seen here ->

int opcode = (i>>24)&0xff

my result is 255, although this extraction method works when the value is positive and reproduces the correct op-code in these cases.

While researching this, I found "How I get the value from the Immediate part of a 32 Bit sequence in C?", which seemingly deals with what I'm asking, however the answer given in that question is exactly what I'm doing, anyone know more?


Solution

  • SIGN_EXTEND looks like it is intended to be used in decoding, to take the 24 bits that have been extracted from the instruction and convert them to a 32-bit signed integer. It looks like it is not intended to be used in encoding. For encoding, IMMEDIATE(x) appears to be intended for that. Given a 32-bit signed integer, it produces a 24-bit signed integer, providing the value fits.

    So:

    unsigned int i = (PUSHC << 24) | SIGN_EXTEND(-2);
    

    should be:

    unsigned int i = (PUSHC << 24) | IMMEDIATE(-2);