mips | MIPS assembler and simulator | Interpreter library
kandi X-RAY | mips Summary
kandi X-RAY | mips Summary
Mips assembler/interpreter in JavaScript (via TypeScript). MIPS is currently a work-in-progress, but it has been tested to run most non-floating-point instruction mips code. See the Road Map for near-future features.
Support
Quality
Security
License
Reuse
Top functions reviewed by kandi - BETA
Currently covering the most popular Java, JavaScript and Python libraries. See a Sample of mips
mips Key Features
mips Examples and Code Snippets
Community Discussions
Trending Discussions on mips
QUESTION
The format for the mips instruction andi $a0, $a0, 0x9AE3
looks correct. It's an I type format opcode rs rt immediate. Why is an invalid mips instruction?
ANSWER
Answered 2021-Jun-14 at 22:33As @Peter says, if the constant is too large to fit in the immediate field, the assembler will either reject that line or translate that into multiple instructions that build some of the constant within the process of doing the operation requested.
However, for andi
the immediate field is 16 bits that are treated as unsigned, which means we get a range of 0x0000-0xFFFF, and 0x9000 is clearly within that range.
Now, if the opcode was addi
, the difference is that for addi
the same 16-bit immediate field is treated as signed, which means we get the range 0xFFFF8000-0x00007FFF, and here 0x9000 is out of that range (so the assembler will either reject that line of assembly code, or substitute with a 2 (or more) instruction sequence, since it cannot be encoded in one instruction).
As a side note, many MIPS assemblers are super friendly, and will take "sensible" instructions and operands that the processor doesn't naturally support and treat them as pseudo instructions that are instead implemented by a sequence of multiple machine code instructions. This is so prevalent in the MIPS mind set as can be evidenced by the reservation of an entire CPU register ($at
/$1
) as temporary storage for such expansions. In RISC V this has gone away, and only pseudo instructions that can reuse the target are allowed and otherwise the (human) assembly programmer has to write an appropriate code sequence (and that might involve identifying a free register). IMHO, this is a good thing, b/c the MIPS assemblers hide things that shouldn't be hidden in assembly — for example, translating some innocent looking instructions into a 3-instruction sequence, and when these occur inside a loop, with some thought, much better could have been done (if the assembly programmer had not had that "assistance" by the assembler and was alerted to consider the situation in terms of what the hardware can more directly).
Let's also note that in RISC V all immediates are sign extended, so they've also removed the different handling of immediate for andi
vs. addi
. As @Peter also notes, the RISC V immediates are smaller as well, and both of these increase the workload of programmers and compilers, but make the hardware more efficient by only needing one hardware mechanism for enlarging immediates (i.e. sign extension and no zero extension), and by making better use of encoding bits (more bits for opcodes, for greater instruction set longevity and custom instruction set expansion).
QUESTION
I am new to MIPS assembly. I am trying to convert a java code to MIPS code but I can't figure it out that how can I load and store double values in MIPS. I get this error "address not aligned on doubleword boundary 0x10010001". Here is the java code:
...ANSWER
Answered 2021-Jun-14 at 17:49Use syscall function code 3 to print doubles (not function code 2 — that's for single float).
Use mov.d
to copy one register to another, e.g. into $f12
for sycalls (then no need to load 0.0 into $f0
).
(Also, use l.d
instead of ldc1
.)
The loop:
loop isn't a loop (there is no backward branch for it).
As @Peter says, your scaling/offsets are not properly accounting for the size of double, which is 8. Scaling needs to multiply by 8 (shift by 3, not 2), and offsets need to be multiples of 8.
Your first loop, when its done, should not EXIT the program but rather continue with the next statement (i.e. the printing loop).
For this statement numbers[i+2] = numbers[i+1] + numbers[i];
there are two loads and one store as array references, whereas the assembly code is doing 3 loads and no store.
You use $s5
, but never put anything in it.
The comparison of numbers[i+1] < 150
has to be done in (double) floating point, whereas the assembly code is attempting this in integer registers.
Floating point comparison is done using c.eq.d
, c.lt.d
, or c.le.d
. Like with integer compares, constants need to be in registers before the compare instruction. 150.0 would best come directly from memory (as a double constant) before the loop and remain there for the loop duration (or you can move integer 150 into a floating point register and convert that to double (cvt.w.d
)).
Conditional branches on floating point compare conditions use either bc1t
or bc1f
(depending on the sense you want).
The C-like pseudo code probably doesn't run properly. The exit condition for the first loop is suspect — it will probably run off the end of the array (depending on its initial data values).
Translating non-working C code into assembly is a recipe for frustration. Suggest getting it working in C first; run it to make sure it works.
QUESTION
I am trying to load a 32-bit constant 0x1234ABCD to register $t0
in MIPS assembly. However, I am not able to use lui
to do so. My instinct is to use two addi
, but I am not sure how to do so. I would necessarily need 2 or more to get the 32 bits of information. I need to get the upper bits set somehow without lui
. What is a good way to approach replicating lui
without using it?
ANSWER
Answered 2021-Jun-09 at 18:14You may use for example ori
combined with sll
to load a 32 bit constant in 3 instructions without using lui
:
QUESTION
We have a code in production that in some situation may left-shift a 32-bit unsigned integer by more than 31 bits. I know this is considered undefined behavior. Unfortunately we can't fix this right now, but we can work this around, if only we can assume how it works in practice.
On x86/amd64 I know processor for shifts uses only the appropriate less-significant bits of the shift count operand. So that a << b
is in fact equivalent to a << (b & 31)
. From the hardware design this makes perfect sense.
My question is: how does this work in practice on modern popular platforms, such as arm, mips, RISC and etc. I mean those that are actually used in modern PCs and mobile devices, not outdated or esoteric.
Can we assume that those behave the same way?
EDIT:
The code I'm talking about currently runs in a blockchain. It's less important how exactly it works, but at the very least we want to be sure that it yields identical results on all the machines. This is the most important, otherwise this can be exploited to induce a so-called chain split.
Fixing this means hassles, because the fix should be applied simultaneously to all the running machines, otherwise we are yet again at risk of the chain split. But we will do this at some point in an organized (controlled) manner.
Lesser problem with the variety of compilers. We only use GCC. I looked at the code with my own eyes, there's a
shl
instruction there. Frankly I don't expect it to be anything different given the context (shift operand comes from arbitrary source, can't be predicted at compile time).Please don't remind me that I "can't assume". I know this. My question is 100% practical. As I said, I know that on x86/amd64 the 32-bit shift instruction only takes 5 least significant bits of the bit count operand.
How does this behave on current modern architectures? We can also restrict the question to little-endian processors.
...ANSWER
Answered 2021-Jun-02 at 20:15With code that triggers undefined behavior, the compiler can just about do anything - well, that's why it's undefined - asking for a safe definition of undefined code doesn't make any sense. Theoretical evaluations or observing the compiler translating similar code or assumptions on what "common practice" might be won't really give you an answer.
Evaluating what a compiler really has translated your UB code to would probably be your only safe bet. If you want to be really sure what happens in the corner cases, have a look at the generated (assembly or machine) code. Modern debuggers give you the toolset to catch those corner cases and tell you what actually happens (the generated machine code is, after all, very well defined). This will be much simpler and much safer than to speculate on what code the compiler might probably emit.
QUESTION
(i1) lw $1,40($2)
(i2) add $2,$3,$3
(i3) add $1,$1,$2
(i4) sw $1,20($2)
...ANSWER
Answered 2021-Jun-07 at 15:18First, let's state that this question applies to a pipelined processor, rather than a single cycle processor.
Second, let's assume that WB
(write back) executes instantly at the beginning of the cycle — this is realistic b/c WB
doesn't have to compute anything and the value for it to store into the register file is available at the very beginning of the cycle.
And that then the ID
from a later instruction can capture the value written by WB
from an earlier instruction, via overlap in the same cycle.
QUESTION
I understood every part of datapath but i couldn't clearly understood how to get memory address of a register. For example, in a hypothetical new instruction like J 200($s1)
(mips language)
...ANSWER
Answered 2021-Jun-04 at 00:48We must start with $s1
's contents -- the value held there. From the 32-bit value held by that register, we can do:
- $s1 + 200 (simple addition), or,
- Mem[$s1 + 200] (displacement addressing), or
- Mem[$s1] + 200 (there's some name for this but it is not a common addressing mode).
In your case, as you want to do PC = 200($s1), my guess would be (1) or (2).
Because assignment to the PC (PC=...) already implies another memory fetch that will occur for the very next instruction — to fetch the machine code instruction to execute — we need to question whether a memory fetch (in the new J
instruction) is desired or not. The syntax J 200($s1)
is ambiguous here (b/c of the implied indirection of the execution cycle: IR=Mem[PC] that naturally occurs during instruction execution), so, you'll have to ask whether the 200($s1) is the simple address of machine code to fetch and execute next (very likely), or, the address of a data pointer that tells where the machine code is.
The former, (1), would be reasonable as the next operation the processor performs is IR = Mem[PC], so across two instructions (this J
and the next instruction), that says execute the instruction at Mem[PC] (where PC=$s1+200) so equivalent to saying to execute the instruction at Mem[$s1+200]: a single level of indirection, which says to use the location, $s1+200, to assign to the PC=$s1+200, and use subsequently as a the location of program/machine code instructions.
IR is the instruction register, used internally to describe the processor's fetch of the machine code instruction and holding of it for decode and further execution.
The latter, (2), would also be reasonable, and it says execute the instruction at Mem[Mem[$s1+200]], an extra level of indirection, appropriate if the intent is to use the memory location, $s1+200, as a data word, as a pointer to the next PC/machine code instruction, to be assigned to the PC so that the next instruction is sourced from that data pointer value.
QUESTION
So I'm new to MIPS and I'm trying to build a program in Assembly MIPS which finds the maximum value in array:
...ANSWER
Answered 2021-Jun-02 at 16:49The problem is you are running your loop using the address of N
and not the value of N
. The first line of main
loads the address of N
into $a0
which becomes $t0
in your max
function. However, you then use that address as if its the value of N
(ie, 8) in your loop with beq $t2 $t0 maxEnd
.
Either just load the value directly into $a0
at the beginning:
QUESTION
I am trying to make a recursive multiplication function in MIPS. The logic is :
We want to multiply x by y.
Base case : x = 0, return y
General case : x != 0, return y + (x-1)*y
So I wrote the code, and everything works fine as expected, except for one little bit. At the beginning of the code, I do :
...ANSWER
Answered 2021-May-28 at 09:04The push operation should pre-decrement the stack pointer. That is, instead of:
QUESTION
I'm currently for the fun of it rewriting the back end of a language we used in a programming language course to target wasm instead of MIPS.
So be very clear I'm not talking about using wasm but creating wasm file and getting it all right.
I'm currently looking on import and export and the webassembly specification (as for now) does not cover how the wasm/js api actually works. For example when importing something like JS console.log function or another function does the JS engine just search the import section and looks for the names encoded and match it with a function?
I know that this is not a "code issues", in the usual way but I can't seem to find the right place to look.
...ANSWER
Answered 2021-May-24 at 08:58I'm currently looking on import and export and the webassembly specification (as for now) does not cover how the wasm/js api actually works.
That's the beauty of a specification, it can have various different implementations!
For example when importing something like JS console.log function or another function does the JS engine just search the import section and looks for the names encoded and match it with a function?
That would seem like a reasonable implementation. When you create a WebAssembly module you supply named import functions, these must match the names in the WebAssembly module's import section.
webassemblyjs is a JavaScript-based WebAssembly interpreter. You can see how it matches externally provided imports with the module's expected imports here:
QUESTION
I am trying to replicate this Java function in MIPS:
...ANSWER
Answered 2021-May-14 at 22:52Found it. The trick in MIPS is that the print out command li $v0, 1
can override the value that you may want to print in $v0, that was my mistake. The work around is to store the data in another register first:
Community Discussions, Code Snippets contain sources that include Stack Exchange Network
Vulnerabilities
No vulnerabilities reported
Install mips
Support
Reuse Trending Solutions
Find, review, and download reusable Libraries, Code Snippets, Cloud APIs from over 650 million Knowledge Items
Find more librariesStay Updated
Subscribe to our newsletter for trending solutions and developer bootcamps
Share this Page