В этом коде пара шестнадцатеричных чисел, которые должны быть lw и sw, не распечатываются.
#include <iostream>
#include <stdio.h>
int main()
{
//char ch[4096];
unsigned int asdf[]={0x022DA822, 0x12A70003, 0x8D930018, 0x02689820, 0xAD930018, 0x02697824, 0xAD8FFFF4,0x018C6020, 0x02A4A825, 0x158FFFF6, 0x8E59FFF0};
char* ch=(char*)asdf;
int br=sizeof(asdf);
//printf("%i\n",int(1) >> 5);
//while((br=read(0,ch,sizeof(ch)))>0) {
int l=br/4;
int* ins_array=(int*)ch;
for(short i=0x0; i<l;i++)
{
int ins=ins_array[i];
int opcode=ins & 0xFC000000;
opcode = opcode >> 26;
//printf("opcode: %i\n",opcode);
int addr=0x7A060+i*4;
switch(opcode)
{
case 0x00:
//add,sub
{
int s=(ins & 0x3E00000)>>21;
int t=(ins & 0x1F0000)>>16;
int d=(ins & 0xF800)>>11;
int tail=ins & 0x7FF;
switch(tail)
{
case 0x20:
//add
printf("%x: add $%i, $%i, $%i\n",addr,d,s,t);
break;
case 0x22:
//sub
printf("%x: sub $%i, $%i, $%i\n",addr,d,s,t);
break;
case 0x24:
//and
printf("%x: and $%i, $%i, $%i\n",addr,d,s,t);
break;
case 0x25:
//or
printf("%x: or $%i, $%i, $%i\n",addr,d,s,t);
break;
case 0x2A:
//slt
printf("%x: slt $%i, $%i, $%i\n",addr,d,s,t);
break;
}
break;
}
case 0x23: //lw
case 0x2B: //sw
case 0x04: //beq
case 0x05: //bne
{
int s=(ins & 0x3E00000)>>21;
int t=(ins & 0x1F0000)>>16;
short I=(ins & 0xFFFF);
short m=65536-I;
short n=(ins & 0xFFFF)<<2;
switch(opcode)
{
case 0x23:
if (I<63)
{
printf("%x: lw $%i, %i($%i)\n",addr,t,I,s);
}
else
{
printf("%x: lw $%i, -%i($%i)\n",addr,t,m,s);
}
break;
case 0x2B:
if (I<63)
{
printf("%x: sw $%i, %i($%i)\n",addr,t,I,s);
}
else
{
printf("%x: lw $%i, -%i($%i)\n",addr,t,m,s);
}
break;
case 0x04:
printf("%x: beq $%i, $%i, address %x\n",addr,s,t,n+addr);
break;
case 0x05:
printf("%x: bne $%i, $%i, address %x\n",addr,s,t,n+addr);
break;
}
break;
}
}
}
}
Моя распечатка выглядит так:
7a060: sub $21, $17, $13
7a064: beq $21, $7, address 7a070
7a06c: add $19, $19, $8
7a074: and $15, $19, $9
7a07c: add $12, $12, $12
7a080: or $21, $21, $4
7a084: bne $12, $15, address 7a05c
Я хочу, чтобы он распечатывался так:
7a060: sub $21, $17, $13
7a064: beq $21, $7, address 7a070
7a068: lw $19, 24($12)
7a06c: add $19, $19, $8
7a070: sw $19, 24($12)
7a074: and $15, $19, $9
7a078: sw $15, -12($12)
7a07c: add $12, $12, $12
7a080: or $21, $21, $4
7a084: bne $12, $15, address 7a05c
7a088: lw $25, -16($18)
Что я должен сделать, чтобы решить эту проблему?
Вот ваша проблема:
int opcode=ins & 0xFC000000;
opcode = opcode >> 26;
opcode
должен быть без знака, в противном случае вы будете выполнять арифметический сдвиг, а не логический сдвиг, и результат будет отрицательным, если бит 31 ins
был установлен.
Сдвиг битов в целых числах со знаком имеет тенденцию вызывать проблемы.
int main()
{
std::cout << boolalpha << hex;
int i = 0x8D930018 & 0xfc000000;
int j = i >> 26;
std::cout << j << " == 0x23: " << (j == 0x23) << std::endl;
unsigned int i2 = 0x8D930018 & 0xfc000000;
unsigned int j2 = i2 >> 26;
std::cout << j2 << " == 0x23: " << (j2 == 0x23) << std::endl;
}Output:
ffffffe3 == 0x23: false
23 == 0x23: true
Вам нужно либо работать с неподписанными целочисленными значениями, либо маскировать интересующие вас биты, например, с
opcode = (opcode >> 26) & 0b111111;