Boa noite, alguém poderia me ajudar nesta?
Terei um arquivo contendo em linguagem de montagem do MIPS ex:
add $1, $2, $3
bne $2, $3, 0x5
Enfim, o arquivo é contem estas instruções é binário e cada uma delas é uma palavra de 32 bits.
Eu devo abrir este arquivo e manipular os bits, porém não consegui ainda fazer essa leitura dos bits dessa forma.
Abrir o arquivo - fopen
Ler 4 bytes - fread
Pegar os 4 bytes e transformar em bits - usar os operadores <<, >>, &, | e ~
Só uma coisinha para te desanimar. Onde você arranjou esse arquivo? Se for um binário como um executável de um Linux portado para MIPS, ele tem muito mais coisas que simplesmente as instruções do processador. Você precisa arranjar a documentação desse formato de arquivo; muitas vezes, um binário desses é link-editado em tempo de execução e coisas importantes (como branches) não aparecem com seus valores corretos e sim como zeros ou então índices para uma tabela de funções que são link-editados no tempo de carregamento do binário.
Então deve ser mais fácil fazer o “disassembly”. Tem certeza que não há nenhuma ferramenta pronta que faça isso por você, ou isso é um trabalho de escola (fazer o “disassembly” das instruções)?
É um trabalho da faculdade, tenho que ler esse arquivo, pegar os 32 bits da instrução e manipular, porém estou desnorteado quanto a primeira parte, que é ler esses bits.
Trabalho pouco com c, por isso não sei exatamente uma forma de faze-lo.
É isso mesmo, a identificação das instruções estão mapeadas nos bits delas, no caso:
add $1, $2, $3
esperasse que tenha 32 bits e a partir dos seis mais significativos(e nesse caso os seis menos significativos também), decodificar a instrução e apresentar ela na linguagem de montagem.
até agora só o que fiz foi tentar ler o arquivo em modo binário.
Evite usar feof() - C não é Pascal, e feof() não é uma boa forma de detectar se o arquivo acabou. O correto é tentar ler e verificar se apareceram menos bytes que o desejado
Ler a documentação não faz mal a ninguém - eu não cantei a bola do fread? Não use getc, não serve para o que você precisa .
Um grande problema, a meu ver, é que não sei no seu arquivo se os bytes estão escritos na ordem natural ou na ordem inversa.
Por exemplo, digamos que um opcode seja uma palavra de 32 bits representada por:
int opcode = 0x12345678;
Nesse seu arquivo, não sei se ele está gravado na ordem natural (ou seja, byte 0 = 0x12, byte 1 = 0x34, byte 2 = 0x56, byte 3 = 0x78 )
ou na ordem inversa (byte 0 = 0x78, byte 1 = 0x56, byte 2 = 0x34, byte 3 = 0x12). É que o processador MIPS pode trabalhar em uma das duas orientações:
Vamos supor, apenas para simplificar, que o arquivo só contenha instruções, que todas as instruções sejam de 32 bits, e que os bytes venham em ordem natural.
Vamos supor também que unsigned int, no seu compilador C, tenha exatamente 32 bits.
Você faria algo como:
...
unsigned int getInstruction (unsigned char bytes[]) {
return (bytes[0] << 24) | (bytes[1]<<16) | (bytes[2] <<8) | bytes[3];
}
...
FILE *f = fopen (....);
unsigned char bytes[4];
unsigned int instruction;
int nBytes;
while ((nBytes = fread (bytes, 1, sizeof(bytes), f) > 0) {
instruction = getInstruction (bytes);
if ((instruction & 0x07FF) == 0x0020)) {
/* Instrução ADD rd, rs, rt */
/* A decodificação desta instrução é por sua conta :) */
}
}