Translating C Code to MIPS Code to Machine Language with Machine Instruction in Binary and Hex Format

The code won’t be exactly translated to MIPS code but similar code is written so the output is same as the c code.

C Code:

#include<stdio.h>

int main(){

    int a = 2;

    // Prints 20 in Hexadecimal which is equivalent to 32 in Decimal
    printf("%x\n", a << 4);

    return 0;
}

Let, $t0 represent a and $t1 represent the output value in Hex.

MIPS Code:

# This is Comment.
# $0 register is always 0.

ori $t0, $0, 2
sll $t1, $t0, 4

The first line of of MIPS code is or immediate. It can be used to load the value 2 into register $t0. Any value or’ed with another value is the same value. Remember $t0 in represents a in the C Code above.

The sll command shifts contents register $t0 by 4 bits. It is equivalent to, $t1 = $t1 << 4. 2 Shifted by 4 bits in decimal is 32 and in Hexadecimal is 20.


Code Execution in MARS:

No lines executed:
mips shifting register values no line executed
mips shifting register values no line executed
First Line executed:
mips shifting register values one line executed
mips shifting register values one line executed
Second Line executed:
mips shifting register values two lines executed
mips shifting register values two lines executed

Machine Language:

Here the first line of MIPS code ori is I-Format and the second line of code sll is R-type / Format instruction.

For the first line,
ori $t0, $0, 2
Machine Instruction in Binary:

Since ori is an I type instruction it will have 4 fields. It has opcode, rs, rt and immediate. $t0 is numbered 8, $0 register is 0. Opcode for ori is 13.

001101 00000 01000 0000000000000010
opcode rs rt immediate
6 bits 5 bits 5 bits 16 bits

In order to convert the binary to Hex format instruction make group in 4 bits.

Machine Instruction Bits in Group of four:
0011 0100 0000 1000 0000 0000 0000 0010
which in Hexadecimal is,
0x34080002

It matches the instruction in the pictures above. Look at the codes column.


Similarly for the 2nd line,
sll $t1, $t0, 4
Machine Instruction in Binary:

Since ori is an I type instruction it will have 6 fields. It has opcode, rs, rt, rd, shamt (shift amount) and funct. Here rs is not used so set to 0. $t0 to $t7 registers are numbered from 8 to 15. So $t0 is numbered 8, $t1 is 9. The Opcode for sll ( Shift Left Logical ) is 0 and funct ( function ) is also 0.

000000 00000 01000 01001 00100 000000
opcode rs rt rd shamt funct
6 bits 5 bits 5 bits 5 bits 5 bits 6 bits

In order to convert the binary to Hex format instruction again make group in 4 bits.

Machine Instruction Bits in Group of four:
0000 0000 0000 1000 0100 1001 0000 0000
which in Hexadecimal is,
0x00084900

Which again matches the instruction in the code column shown above.

Advertisements

UVA Problem 10189 – Minesweeper Solution

UVA Problem 10189 – Minesweeper Solution:


Click here to go to this problem in uva Online Judge.

Solving Technique:

Given a mine field that is a matrix / 2D array, produce an output that contains count of adjacent mines for each squares.

In a 2D array for each squares there are at most adjacent 8 squares. If the current position is i and j then,

\begin{bmatrix}  (i-1,j-1) & (i-1,j) & (i-1,j+1) \\  (i+0,j-1) &  (i,j)  & (i+0,j+1) \\  (i+1,j-1) & (i-1,j) & (i+1,j+1) \\   \end{bmatrix}

Just traverse the matrix row-column wise and check its adjacent squares for getting mine count for current position. The adjacent squares check can be implemented with 8 if conditions for each one.

Another technique is to store the co-ordinates of adjacent squares and using a for loop to check them. The illustration below shows how the 2nd code is implemented using arrays and for loops,
uva 10189 matrix adjacent squares check with saved co-ordinates and for loop
uva 10189 matrix adjacent squares check with saved co-ordinates and for loop

Here the arrow from the center shows where checking starts. The 1D arrays drow and dcol hold the row and column values the way shown above. It can be changed by modifying drow and dcol arrays.

 

Important:  Be sure to add or print a new line after each output unless otherwise specified. The outputs should match exactly because sometimes even a space character causes the answer to be marked as wrong answer. Please compile with c++ compiler as some of my codes are in c and some in c++.


More Inputs of This Problem on uDebug.


Input:

4 4
*...
....
.*..
....
3 5
**...
.....
.*...
0 0

 


Output:

Field #1:
*100
2210
1*10
1110

Field #2:
**100
33200
1*100

Code Using Multiple if Conditions:

/**
 * Author:    Asif Ahmed
 * Site:      https://quickgrid.wordpress.com
 * Problem:   UVA 10189 - Minesweeper
 * Technique: 2D Array / Matrix Boundary checking using
 *            if conditions.
 */

#include<stdio.h>
#include<string.h>


#define MAXSIZE 101


static char MineField[MAXSIZE][MAXSIZE];



int main(){

    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);


    int n, m;

    int FieldNumber = 0;

    while( scanf("%d%d", &n, &m), n ){

        getchar();

        for(int i = 0; i < n; ++i)
            scanf("%s", &MineField[i]);


        if( FieldNumber )
            printf("\n");


        for(int i = 0; i < n; ++i){
            for(int j = 0; j < m; ++j){

                if( MineField[i][j] == '*' )
                    continue;

                int temp = 0;

                if( i + 1 < n && MineField[i + 1][j] == '*' )
                    ++temp;
                if( i + 1 < n && j + 1 < m && MineField[i + 1][j + 1] == '*' )
                    ++temp;
                if( j + 1 < m && MineField[i][j + 1] == '*' )
                    ++temp;
                if( i - 1 >= 0 && j + 1 < m && MineField[i - 1][j + 1] == '*' )
                    ++temp;
                if( i - 1 >= 0 && MineField[i - 1][j] == '*' )
                    ++temp;
                if( i - 1 >= 0 && j - 1 >= 0 && MineField[i - 1][j - 1] == '*' )
                    ++temp;
                if( j - 1 >= 0 && MineField[i][j - 1] == '*' )
                    ++temp;
                if( i + 1 < n && j - 1 >= 0 && MineField[i + 1][j - 1] == '*' )
                    ++temp;


            MineField[i][j] = temp + '0';

            }
        }


        printf("Field #%d:\n", ++FieldNumber);


       for(int i = 0; i < n; ++i){
            for(int j = 0; j < m; ++j)
                putchar(MineField[i][j]);
            printf("\n");
       }

    }

    return 0;
}

Code Bound checking using Array & for Loop:

/**
 * Author:    Asif Ahmed
 * Site:      https://quickgrid.wordpress.com
 * Problem:   UVA 10189 - Minesweeper
 * Technique: 2D Array / Matrix Boundary checking using
 *            co-ordinate array and for loop.
 */

#include<stdio.h>
#include<string.h>


#define MAXSIZE 101


static char MineField[MAXSIZE][MAXSIZE];


// Co-ordinates / directions of adjacent 8 squares.
// W, SW, S, SE, E, NE, N, NW
static const int drow[] = {0, 1, 1, 1, 0, -1, -1, -1};
static const int dcol[] = {-1, -1, 0, 1, 1, 1, 0, -1};



int main(){

    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);


    int n, m;

    int FieldNumber = 0;

    while( scanf("%d%d", &n, &m), n ){

        getchar();

        for(int i = 0; i < n; ++i)
            scanf("%s", &MineField[i]);


        if( FieldNumber )
            printf("\n");


        for(int i = 0; i < n; ++i){
            for(int j = 0; j < m; ++j){

                int temp = 0;

                // If mine found do nothing.
                if( MineField[i][j] == '*' )
                    continue;


                // For each adjacent squares of the current square calculate mine count.
                // and set the count in current square.
                for(int k = 0; k < 8; ++k){

                    // Check if out of bound of the 2D array or matrix.
                    if( i + drow[k] < 0 || j + dcol[k] < 0 || i + drow[k] >= n || j + dcol[k] >= m )
                        continue;

                    // Check the appropriate co-ordinate for mine, if mine found increase count.
                    if( MineField[i + drow[k] ][j + dcol[k]] == '*' )
                        ++temp;

                }

                // All adjacent squares checked set the mine count for current squares.
                MineField[i][j] = temp + '0';

            }
        }


        printf("Field #%d:\n", ++FieldNumber);


       for(int i = 0; i < n; ++i){
            for(int j = 0; j < m; ++j)
                putchar(MineField[i][j]);
            printf("\n");
       }

    }

    return 0;
}