4

For an academic problem, given the following big-endian MIPS code (highest memory address at left, lowest at right), I have been asked to provide the MIPS code from hex and its equivalent C code, as well as some context to the C code.

80 48 05 00 20 48 89 00 00 00 28 8d 04 00 2a ad 00 00 2a ad 04 00 28 ad 08 00 e0 03

I have disassembled the MIPS code and converted it into some C code. I wanted to know if I mess up the byte ordering during the disassembling process since the C code doesn't seem to have a purpose rather than variable assignments, or if I mess up the C code so that it appears to be irrelevant.

Please note that the initializations of the variables and array size are just placeholders (they are not part of the MIPS code at all), so that the program can run with error.

Any help is much appreciated!

MIPS:

Big Endian  Little Endian   Binary Representation (Little Endian)   MIPs Code
80480500    00054880        000000 00000 00101 01001 00010 000000   sll $t1, $a1, 2
20488900    00894820        000000 00100 01001 01001 00000 100000   add $t1, $a0, $t1
0000288d    8d280000        100011 01001 01000 0000000000000000     lw $t0, 0x0000($t1)
04002aad    ad2a0004        101011 01001 01010 0000000000000100     sw $t2, 0x0004($t1)
0000a2ad    ad2a0000        101011 01001 01010 0000000000000000     sw $t2, 0x0000($t1)
040028ad    ad280004        101011 01001 01000 0000000000000100     sw $t0, 0x0004($t1)
0800e003    03e00008        000000 11111 00000 00000 00000 001000   jr $ra

C:

#include <stdio.h>

int main(void) {
  int i = 0, t0 = 1, t2 = 2;
  int A[10];

  t0 = A[i];
  A[i + 1] = t2;
  A[i] = t2;
  A[i] = t0;

  return 0;
}
  • 1
    Does this answer your question? [How do I disassemble raw MIPS code?](https://stackoverflow.com/questions/9916130/how-do-i-disassemble-raw-mips-code) – Agnius Vasiliauskas Aug 14 '20 at 08:49
  • 1
    This problem is under specified as you've stated it. Saying some binary blob needs to be converted from bit-endian to little-endian leaves out how large each value to be converted is. Are they 32-bit `int` values? 64-bit `long long` values? 16-bit `uint16_t` values? Some mix of all those? You can't just say "This is big-endian, convert it to little-endian". – Andrew Henle Aug 14 '20 at 09:34
  • @AndrewHenle, they are MIPS instructions, which can generally be taken as 32-bits, and especially so in educational settings if they don't specify otherwise. – Erik Eidt Aug 14 '20 at 16:20

2 Answers2

1

Your disassembly looks good.

You described the C code as a parameterless main with integer return value, having local variables.

However, let's note that $a0, and $a1 are uninitialized yet used.  Further they are MIPS calling convention parameter registers.

Uninitialized parameter registers might be taken as parameters.

In MIPS calling convention, $v0 is the return value register.  But it is never set, so this fragment is not returning a value.

Thus, it is possible that the signature of the function is two parameters and no return value.

We cannot know the whole function, though, because $t2 is also uninitialized, but not a parameter register.  Obviously missing code also throws into question whether $a0 and $a1 are actually parameters or are simply local variables.  Further, as there is missing machine code, it is also possible that there is a return value but we don't see it.

If it was me I would write the C as a function with two parameters ($a0, $a1) of the types you used.  I would describe $t2 as a local variable initialized with ? aka unknown, but I would also add a caveat note that this is a guesstimate due to incompleteness of the machine code fragment.

Erik Eidt
  • 23,049
  • 2
  • 29
  • 53
0

Most of time, endianess convertion can be done with htonl() or ntohl().

A quick implementation can be :

int iIn, iOut;
char *pIn, *pOut;

iIn = 0x123456789;

pIn = (char*) &iIn;
pOut = (char*) &iOut;

pOut[0] = pIn[3];
pOut[1] = pIn[2];
pOut[2] = pIn[1];
pOut[3] = pIn[0];
Emmanuel DUMAS
  • 680
  • 10
  • 25