Reputation: 21
I have to write program that converts mips instruction to binary just like it is done on this website: http://www.mipshelper.com/mips-converter.php
Please someone help. I need to write a mips code
If i write on console:
add $t0, $t1, $t2
it should result
00000001001010100100000000100000
Upvotes: 1
Views: 15574
Reputation: 2090
You can see a program I'm still developing for parsing MIPS assembly instructions to binary representation in a format suitable for $readmemb() of verilog. Check this out. The program is written in C.
https://www.dropbox.com/sh/vkmfcytlc01yqwf/AACmLEBsN3rhjo9TBVO0RPUCa?dl=0
Yet it parses R-format instructions (add, sub, or, and, slt), I-format (beq, bne, lw, sw), but not yet J-format. It's trivial to implement them.
I haven't refreshed the README yet, but you can execute it with the -c option which transfers the parsed instruction as a comment after encoded line (./masmbin -c input.masm ouput.mbin).
The key is to be aware of the properties of each instruction. E.g. in the lw/sw, we have
lw rt, #n(rs)
Note that the registers are in reverse order, in contrast with the order that should be encoded in the binary representation:
[opcode][ rs ][ rt ][immediate]
Good luck!
EDIT: There is also a work in progress (a remake from me) here.
Upvotes: 1
Reputation: 1076
Darn it, I read the question backwards, and came up with a cool way to turn the binary into an opcode. But it might point (heh) you in the right direction: using an array of pointers as an index to a bunch of strings. I'm going to describe the (simpler) binary-to-opcode concept first, then adapt the idea for opcode-to-binary.
First, the question you didn't ask: binary into opcode. Consider using the bits of each section of the instruction word as a displacement (pointer) into an array that then points you to the appropriate string. At least, I think that's what I'd do.
Let's see how that would work for translating the last 6 bits of an R-type instruction (using the Green Sheet). I'm just going to do the first four: 0 = sll, 1 = invalid, 2 = srl, 3 = sra. Here's the data segment, where I've defined strings (not necessarily in order) and a vector table (which is in order).
.data
.functNames
f_invalid: .asciiz "invalid_funct"
f_sll: .asciiz "sll"
f_srl: .asciiz "srl"
f_sra: .asciiz "sra"
.align 2
.functXref
.word f_sll # 0
.word f_invalid # 1
.word f_srl # 2
.word f_sra # 3
Now for the code. For the "funct", we want to mask out all but the 6 bits we're looking at, then shift left twice to make it a word pointer. (For the others, you'd need to shift right.)
.text
# assume $s0 contains the 32-bit MIPS instruction
andi $t0, $s0, 0x0000003F
sll $t0, $t0, 2
# get pointer to the string
lw $t1, functxref($t0)
# get address of the string
lw $t2, 0($t1)
Now you have the address of the string detailing the instruction (for an R-type with opcode 0).
Finally, the question you asked: how do you get started converting the text to the binary? Maybe you can use a similar array of strings and pointers to strings. Loop through the possible strings until you find a match (or run out of strings to compare). You would need to set up a parallel array to indicate what sort of opcode it is, and what the associated bit pattern would be:
.opcodeNames
f_add: .asciiz "add"
f_addi: .asciiz "addi"
f_j: .asciiz "j"
.align 2
.opcodeXref
.word f_add
.word f_addi
.word f_j
.opcodeTypes
ft_add: .byte 'R'
ft_addi: .byte 'I'
ft_j: .byte 'J'
.opcodeVals
fv_add: .byte 0x20
fv_addi: .byte 0x08
fv_j: .byte 0x02
Get the pointer from opcodeXref
, use that to get the string from opcodeNames
, and see if it's a match. If not, go to the next word in opcodeXref
.
If it's a match, then use the same index you're at in opcodeXref
to get the format from .opcodeTypes
, then get the bit pattern from .opcodeVals
.
Hope that's enough to get started. Sounds like a pretty big project, especially with all that string manipulation (not something Assembler is really intuitive for).
Upvotes: 0