シフトを行いながら符号を保持しながら、16進数を10進数に変換しようとしています。署名された指示を適切に逆アセンブルするために私の 'simm'変数を得ることに問題がある。ここで符号付きビットシフト
void disassembleInstr(uint32_t pc, uint32_t instr) {
uint32_t opcode; // opcode field
uint32_t rs, rt, rd; // register specifiers
uint32_t shamt; // shift amount (R-type)
uint32_t funct; // funct field (R-type)
uint32_t uimm; // unsigned version of immediate (I-type)
int32_t simm; // signed version of immediate (I-type)
uint32_t addr; // jump address offset field (J-type)
opcode = instr >> 26;
rs = (instr >> 21) & 0x1f;
rt = (instr >> 16) & 0x1f;
rd = (instr >> 11) & 0x1f;
shamt = (instr >> 6) & 0x1f;
funct = (instr & 0x3f);
uimm = instr & 0xffff;
simm = (instr << 16) >> 16; // shift sign bit to left to
addr = instr & 0x3ffffff; //masked with one
cout << hex << setw(8) << pc << ": ";
switch(opcode) {
case 0x00:
switch(funct) {
case 0x00: cout << "sll " << regNames[rd] << ", " << regNames[rs] << ", " << dec << shamt; break;
case 0x03: cout << "sra " << regNames[rd] << ", " << regNames[rs] << ", " << dec << shamt; break;
case 0x08: cout << "jr " << regNames[rs]; break;
case 0x10: cout << "mfhi " << regNames[rd]; break;
case 0x12: cout << "mflo " << regNames[rd]; break;
case 0x18: cout << "mult " << regNames[rs] << ", " << regNames[rt]; break;
case 0x1a: cout << "div " << regNames[rs] << ", " << regNames[rt]; break;
case 0x21: cout << " addu " << regNames[rd] << ", " << regNames[rs] << ", " << regNames[rt]; break;
case 0x23: cout << " subu " << regNames[rd] << ", " << regNames[rs] << ", " << regNames[rt]; break;
case 0x2a: cout << " slt " << regNames[rd] << ", " << regNames[rs] << ", " << regNames[rt]; break;
default: cout << "unimplemented";
}
break;
case 0x02: cout << "j " << hex << ((pc + 4) & 0xf0000000) + addr * 4; break;
case 0x03: cout << "jal " << hex << ((pc + 4) & 0xf0000000) + addr * 4; break;
// case 0x04: cout << "beq " << regNames[rs] << ", " << regNames[rt] << ", " << + uimm; break;
// case 0x05: cout << "bne " << regNames[rs] << ", " << regNames[rt] << ", " << + uimm; break;
// case 0x09: cout << "addiu " << regNames[rt] << ", " << regNames[rs] << dec << simm; break;
// case 0x0c: cout << "andi " << regNames[rt] << ", " << regNames[rs] << dec << simm; break;
case 0x0f: /* lui */ break;
case 0x1a: cout << "trap " << hex << addr; break;
case 0x23: /* lw */ break;
case 0x2b: /* sw */ break;
default: cout << "unimplemented";
}
cout << endl;
}
は私が取得しています間違った出力の例です:
ここ400000: j 400114
400004: sw $ra, fffc($sp)
400008: sw $fp, fff8($sp)
40000c: addiu $fp, $sp, 65528
400010: addiu $sp, $fp, 65124
400014: addiu $k1, $zero, 1
は、目的の出力です:
400000: j 400114
400004: sw $ra, -4($sp)
400008: sw $fp, -8($sp)
40000c: addiu $fp, $sp, -8
400010: addiu $sp, $fp, -412
400014: addiu $k1, $zero, 1
編集:実装の提案で新しい出力:
400000: j 400114
400004: sw $ra, fffffffc($sp)
400008: sw $fp, fffffff8($sp)
40000c: addiu $fp, $sp, -8
400010: addiu $sp, $fp, -412
400014: addiu $k1, $zero, 1
ISAを?アセンブラ? – awiebe
C++を使用してバイナリをアセンブリに変換する – Nathan1324