HL Programming: Mini-Assembler in Java

In summary: HALT": returnValue = 10; break; default: returnValue = 0; } return returnValue; } private static byte makeI(byte opcode, byte rs, byte rt, short immed) { byte returnValue = 0; String upperCase = r.to
  • #1
Margarita0076
5
0
Homework Statement
Assembler.java
Relevant Equations
Create a mini-Assembler for a 32-bit MIPS processor.
I already wrote the regToByte method, but I don't understand how to write the makeI and makeR methods correctly.

Create a mini-Assembler for a 32-bit MIPS processor; Program should accept input lines from the user until HALT is read. With each line, translate the line into MIPS machine code. Print the total memory space needed for the completed program.

Conditions:

The form for all assembly lines will be:

<code> <rd> <rs> <rt> (for codes ADD, AND);
<code> <rd> <rt> <shift_amount> (for codes SRL, SLL);
<code> <rt> <rs> <immediate> (for codes ADDI, ANDI);
BEQ <rs> <rt> <branch_address>;
LW <rt> immediate <rs>; SW <rt> immediate <rs>

Your Assembler should accept the following subset of the complete ISA:

Functions: ADD, ADDI, AND, ANDI, BEQ, LW, SW, SRL, SLL; Registers: $zero, $v0-1, $a0-3, $t0-9, $s0-7.

Immediates and shift amounts should be read in decimal. Branch addresses should be read as a decimal offset from PC+4 (positive or negative). That is, you don't need to do any address arithmetic, just use the immediate given.

Printing a 32-bit binary number can be done in Java with the following: System.out.println("***: " + String.format("%32s", Integer.toBinaryString(word)).replace(" ", "0"));

Mod note: Added code tags
Java:
import java.util.Scanner;

public class Assembler
{
   private static final boolean TEST_MODE = true;

   public static void main(String[] args)
   {
      int count = 0;

      if (TEST_MODE)
      {
         testCases();
      }
      else
      {
         System.out.println("Assembler - Your Name Here\n");

        [B] // Your code here[/B]
        
         System.out.println("\n*** Assembly complete. Program required " + count + " words of memory.");
      }
   }

   [B]private static int makeR(byte opcode, byte rs, byte rt, byte rd, byte shamt, byte funct)
   {[/B]
      int returnValue = 0;
     
      return returnValue;
   [B]}[/B]

  [B] private static int makeI(byte opcode, byte rs, byte rt, short immed)
   {[/B]
      int returnValue = 0;
     
      return returnValue;
   [B]}[/B]

  [B] private static byte regToByte(String r)
   {[/B]
      byte returnValue = 0;
      String upperCase = r.toUpperCase();

      switch(upperCase)
      {
         case "$AT":
            returnValue = 1;
            break;
         case "$ZERO":
            returnValue = 0;
            break;
         case "$V0":
            returnValue = 2;
            break;
         case "$V1":
            returnValue = 3;
            break;
         case "$A0":
            returnValue = 4;
            break;
         case "$A1":
            returnValue = 5;
            break;
         case "$A2":
            returnValue = 6;
            break;
         case "$A3":
            returnValue = 7;
            break;
         case "$T0":
            returnValue = 8;
            break;
         case "$T1":
            returnValue = 9;
            break;
         case "$T2":
            returnValue = 10;
            break;
         case "$T3":
            returnValue = 11;
            break;
         case "$T4":
            returnValue = 12;
            break;
         case "$T5":
            returnValue = 13;
            break;
         case "$T6":
            returnValue = 14;
            break;
         case "$T7":
            returnValue = 15;
            break;
         case "$T8":
            returnValue = 24;
            break;
         case "$T9":
            returnValue = 25;
            break;
         case "$S0":
            returnValue = 16;
            break;
         case "$S1":
            returnValue = 17;
            break;
         case "$S2":
            returnValue = 18;
            break;
         case "$S3":
            returnValue = 19;
            break;
         case "$S4":
            returnValue = 20;
            break;
         case "$S5":
            returnValue = 21;
            break;
         case "$S6":
            returnValue = 22;
            break;
         case "$S7":
            returnValue = 23;
            break;
      }
      return returnValue;
  [B] }

   /*************************************************************
    *
    *   Test Code below
    *   Do NOT modify
    *
    ************************************************************/[/B]
  
   private static void testCases()
   {
      if (test_regToByte())
         System.out.println("RegToByte working well\n");
      else
         System.out.println("RegToByte failed\n");

      if (test_makeR())
         System.out.println("makeR working well\n");
      else
         System.out.println("makeR failed\n");

      if (test_makeI())
         System.out.println("makeI working well\n");
      else
         System.out.println("makeI failed\n");
   }

   private static boolean test_regToByte()
   {
      boolean passedTest = true;
      String[] regs = { "$ZERO", "$AT", "$V0", "$V1", "$A0", "$A1", "$A2", "$A3", "$T0", "$T1", "$T2", "$T3", "$T4",
            "$T5", "$T6", "$T7", "$S0", "$S1", "$S2", "$S3", "$S4", "$S5", "$S6", "$S7", "$T8", "$T9" };

      for (int i = 0; i < regs.length; i++)
      {
         passedTest &= testReg(regs[ i], i);
      }

      return passedTest;
   };

   private static boolean testReg(String regName, int expValue)
   {
      if (regToByte(regName) != expValue) System.out.printf("Fail: regToByte(\"%s\") = %d, should be %d\n", regName, regToByte(regName), expValue);
      return regToByte(regName) == expValue;
   }

   private static boolean test_makeR()
   {
      boolean passedTest = true;
     
      int i = makeR((byte) 1, (byte) 1,(byte) 1,(byte) 1,(byte) 1,(byte) 1);
      if (i != 0b00000100001000010000100001000001)
      {
         System.out.println("Test: makeR(1,1,1,1,1,1) = " + Integer.toBinaryString(i) + " failed");
         passedTest = false;
      }

      i = makeR((byte) 63, (byte) 0,(byte) 31,(byte) 0,(byte) 31,(byte) 0);
      if (i != 0b11111100000111110000011111000000)
      {
         System.out.println("Test: makeR(63,0,31,0,31,0) = " + Integer.toBinaryString(i) + " failed");
         passedTest = false;
      }

      return passedTest;
   };

   private static boolean test_makeI()
   {
      boolean passedTest = true;
     
      int i = makeI((byte) 1, (byte) 1,(byte) 1,(short) 1);
      if (i != 0b00000100001000010000000000000001)
      {
         System.out.println("Test: makeI(1,1,1,1) = " + Integer.toBinaryString(i) + " failed");
         passedTest = false;
      }

      i = makeI((byte) 63, (byte) 0,(byte) 31,(short) 0);
      if (i != 0b11111100000111110000000000000000)
      {
         System.out.println("Test: makeI(63,0,31,0) = " + Integer.toBinaryString(i) + " failed");
         passedTest = false;
      }

      i = makeI((byte) 63, (byte) 0,(byte) 31,(short) -1);
      if (i != 0b11111100000111111111111111111111)
      {
         System.out.println("Test: makeI(63,0,31,-1) = " + Integer.toBinaryString(i) + " failed");
         passedTest = false;
      }

      return passedTest;
   };

}

Аssembler can read and translate one line at a time. It does not need to read in the whole file first. In the example below, I cut and pasted nine lines into the running program. So you main program can be something like:
Until HALT ---- Read a line ------ Translate it ------- Print it

Output:


Assembler - Your Name Here

*** Begin entering Assembler:

ADD $v0 $v1 $zero
AND $a0 $a1 $a2
ADDI $a3 $t4 -321
ANDI $t0 $t5 123
BEQ $s0 $t1 +517
LW $s1 -12 $t2
SW $s2 20 $t3
SRL $a2 $a3 3
SLL $a3 $a2 31
HALT
***: 00000000011000000001000000100000
***: 00000000101001100010000000100100
***: 00100001100001111111111010111111
***: 00110001101010000000000001111011
***: 00010010000010010000001000000101
***: 10001101010100011111111111110100
***: 10101101011100100000000000010100
***: 00000000000001110011000011000010
***: 00000000000001100011111111000000

*** Assembly complete. Program required 9 words of memory.
 
Last edited by a moderator:
Physics news on Phys.org
  • #2
You need to post code in [code] tags. Otherwise the bbCode parser will see [i] and interpret it as an opening italic tag. This makes your code difficult for the reader to follow. [code] also preserves indentation, again making your code clearer.

Mod note: I added code tags
 
Last edited by a moderator:
  • #3
Margarita0076 said:
Homework Statement:: Assembler.java
Relevant Equations:: Create a mini-Assembler for a 32-bit MIPS processor.

I already wrote the regToByte method, but I don't understand how to write the makeI and makeR methods correctly.
The first step would be to find out what makeI and makeR actually are supposed to do. If you can't write that down, I don't think you will get far with systems programming.
 
  • Like
Likes Mark44
  • #4
This is my first time encountering bit encryption in Java. My methods:

int makeR(byte opcode, byte rs, byte rt, byte rd, byte shamt, byte funct)
Constructs a 32-bit integer from the component parts for an R-type instruction.

int makeI(byte opcode, byte rs, byte rt, short immed)
Constructs a 32-bit integer from the component parts for an I-type instruction.

byte regToByte(String r)
Converts a string representation of a register to its numeric equivalent. For example, if you pass in “$s5”, it will return 21. Why 21? Check you green sheet, bottom righthand corner).
 
  • #5
Margarita0076 said:
int makeR(byte opcode, byte rs, byte rt, byte rd, byte shamt, byte funct)
Constructs a 32-bit integer from the component parts for an R-type instruction.
Please describe what needs to be done by the function, in such a way that someone can build it. Do you want the research, the design AND the implementation to be done by the internet?
Hint: Do you have any experience with bit fields? (don't use c bitfields, but you need to make them yourself)
 
  • #6
Margarita0076 said:
This is my first time encountering bit encryption in Java.
In this case, it's encoding; not encryption ##-## an 'assembler' produces machine instructions ('opcode') from mnemonic (readily-memorizable) 'source code' instructions.
 
  • #7
Do you understand the formats of the R-type and I-type instructions? If you're expected to write code that generates MIPS instructions, you need to have a clear understanding of how the instructions are laid out and what each field represents.
Margarita0076 said:
int makeR(byte opcode, byte rs, byte rt, byte rd, byte shamt, byte funct)
Constructs a 32-bit integer from the component parts for an R-type instruction.
An R-format instruction has 6 fields, listed from most significant bits to least significant:
opcode - 6 bits
Rs field - 5 bits - first source register
Rt field - 5 fits - second source register
Rd field - 5 bits - destination register
Shamt field - 5 bits - shift amount
Function code - 6 bits - the specific R-format instruction

Margarita0076 said:
int makeI(byte opcode, byte rs, byte rt, short immed)
Constructs a 32-bit integer from the component parts for an I-type instruction.
An I-format instruction has 4 fields, listed from most significant bits to least significant:
opcode - 6 bits
Rs field - 5 bits - first source register
Rt field - 5 fits - second source register (can be destination register for some instructions)
Immediate or offset field - 16 bits - Holds the immediate value for instructions such as addi, andi, etc. Holds the offset value for instructions such as lw, lb, sw, etc.
 
Last edited:
  • Like
Likes Margarita0076 and sysprog
  • #8
@Margarita0076, are you still stuck? You've started three threads, but haven't returned to any of them to let us know if you have been successful.
 

FAQ: HL Programming: Mini-Assembler in Java

What is HL Programming?

HL Programming is a type of programming that involves creating high-level code that can be easily understood by humans, and then translating it into low-level code that can be understood by computers. It is often used in software development to make the coding process more efficient and user-friendly.

What is a Mini-Assembler?

A Mini-Assembler is a simplified version of an assembler, which is a type of programming language used to convert assembly code into machine code. It typically has a smaller set of instructions and is designed for simpler tasks, making it easier for beginners to learn and use.

Why use Java for a Mini-Assembler?

Java is a popular and versatile programming language that is widely used in various industries. It is known for its simplicity, flexibility, and platform independence, making it a great choice for creating a Mini-Assembler that can run on different operating systems.

How does a Mini-Assembler work?

A Mini-Assembler works by taking in high-level code written in assembly language, which uses mnemonic instructions to represent machine code, and translating it into machine code that can be executed by the computer. It typically follows a specific syntax and uses a symbol table to keep track of memory addresses.

What are the benefits of learning and using a Mini-Assembler in Java?

Learning and using a Mini-Assembler in Java can have several benefits, including improving your understanding of low-level programming, gaining a deeper understanding of how computers work, and developing critical thinking and problem-solving skills. It can also be a useful tool for creating simple programs and can serve as a foundation for learning other programming languages.

Similar threads

Replies
12
Views
2K
Replies
1
Views
2K
Replies
1
Views
2K
Replies
9
Views
2K
Replies
3
Views
2K
Replies
2
Views
4K
Replies
2
Views
2K
Back
Top