I have this case statement in C:
case GOTO: {
int o1 = (int)P[pc+1];
unsigned int o2 = (unsigned)P[pc+2];
int offset =(o1<<8) | o2;
pc = pc + (int)offset;
break;
}
Now about the code:
P[pc+x] will give a 1 byte integer.
And basically at the end of this, I want to set pc to a signed 4 byte int. It's not doing that however. What it is doing is taking the 1 byte, shifting it over, then taking the second byte and then bitwise or, and simply adding it. It is not taking into account the sign of o1. So, if P[pc+1] = FF, and P[pc+2] = E1, what is happening is offset = 0000FFE1. What I want however, is offset = FFFFFFE1. Basically, the first 2 bytes should take the sign of P[pc+1]. But this is not happening. What am I doing wrong?
Check this out if this makes sense for you: #include
int main(void) {
short pc1= 0xFF;
short pc2= 0xE1;
int pc = 0;
unsigned int highbits = 0xFFFFFFFF;
// Check for sign bit, if true OR with highbits
// to set all remaining bits to high
int o1 = pc1 & 0xF0 ? pc1 | highbits : pc1;
int offset = (int)( (o1<<8) | pc2 );
pc = pc + (int)offset;
printf("\npc1=%x pc2=%x pc=%x", pc1, pc2, pc);
printf("\n");
return 0;
}
OUTPUT:
pc1=ff pc2=e1 pc=ffffffe1
I didn't see the declaration of P, but when you say it's a byte array, I'm assuming the specific type it has is unsigned char.
If it were signed, the cast would behave the way you wanted, because, for instance, a -1 char would become -1 int, the sign bit shifted and the remaining bits inverted as required. But when you cast from unsigned char to signed int the result will always be a positive int.
So, to solve the problem, one way is to cast the pointer/array before dereferencing it, and it'll give the desired result:
int o1 = (int)(((char *)P)[pc+1]);
One other thing: a bit shift won't work well with signed values, because it'll simply shift away the sign bit. It would work in your example, because you have 0xFF, but if you had 0x80 it'd be 0x80000000 as int, and become 0x00000000 after the shift.
So, instead of an 8-bit shift, do a multiplication:
int offset =(int)( (o1 * 256) + o2 );
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With