tags:

views:

540

answers:

2

I'm trying to learn MIPS Assembly by learning MIPS Assembly Language Programming. In the book I have this code(extracted from the page 37 of the book):

.data
prompt: .asciiz "\n Please Input a Value: "
bye: .asciiz "\n Bye!"
.globl main
.text

main:
   li $v0, 4
   la $a0, prompt
   syscall

   li $v0, 5
   syscall
   beqz $v0, end
   move $a0, $v0
   li $v0, 1
   syscall
   b main


end:
   li $v0, 4
   la $a0, bye
   syscall

   li $v0, 10
   syscall

I have a cross-compiled binutils targeted to mips-elf, but when I've tried to Assemble the code, I got some errors

ubuntu@eeepc:~/Desktop$ mips-elf-as test-mips.asm
test-mips.asm: Assembler messages:
test-mips.asm:8: Error: illegal operands 'li'
test-mips.asm:9: Error: illegal operands 'la'
test-mips.asm:12: Error: illegal operands 'li'
test-mips.asm:14: Error: illegal operands 'beqz'
test-mips.asm:15: Error: illegal operands 'move'
test-mips.asm:16: Error: illegal operands 'li'
test-mips.asm:22: Error: illegal operands 'li'
test-mips.asm:23: Error: illegal operands 'la'
test-mips.asm:26: Error: illegal operands 'li'
ubuntu@eeepc:~/Desktop$

I'm using x86 Ubuntu Hardy Herron to cross-compile to MIPS

What is wrong?

+3  A: 

Well, the li and la instructions are pseudo instructions which should be recognised by the assembler but it's possible your environment needs to do something to define them (it wouldn't surprise me if they were macros).

Try changing them to their "real" form:

li $v0,4   -->   lui $v0,0;       ori $v0,$v0,4
la $a0,bye -->   lui $a0,bye>>16; ori $a0,$a0,bye&ffff

Or whatever your particular MIPS assembler uses for RIGHT-SHIFT-16-BITS and AND.

The ls instruction I've never seen before. Are you sure that's not a typo for la? And I think beqz should be beq. Most CPUs would use the same instruction in different ways, an example being that both decrementing a register down to zero (z) and comparing a register with something (eq) would set the zero flag.

None of ls, beqz or move show up in the MIPS assembler Wikipedia page although the latter two are listed as pseudo-instructions in Patterson & Hennessy.

So it's looking more and more like there's some extra set-up you need to do to get the pseudo-instructions working.

paxdiablo
Sorry about the `ls`, it was just my mistake.
Nathan Campos
If I try to change, I just got more `illegal operands` error, but now with `lui` and `ori`.
Nathan Campos
Take a look on the page of that book, the code is like that. Now I've copied and pasted.
Nathan Campos
Sorry, @Nathan, that's about the extent of my help. If it's complaining about the lui, it's not a pseudo-instruction problem. Basically, the only instructions working there are syscall and b. I'd be tempted to think it was an assembler for a different CPU is that weren't the case.
paxdiablo
Thanks for the help mate. I'm going to wait for someone that can help me on this.
Nathan Campos
+2  A: 

I think the problem is that you're using an older version of binutils which does not support the symbolic names for MIPS registers.

binutils 2.17 (as referenced in the cross-compilation instructions you linked to) does not understand $v0, $a0 etc. (see this question).

However, if you are building the tools yourself anyway, a good solution would be to move to a later version of binutils: versions from 2.18 onwards do support symbolic register names. Your example assembles correctly with either 2.18 or the latest version, 2.20.

Matthew Slattery
Good catch! All the instructions that are failing have the $v0/$a0-type operands (except the first 'la' which is a bit strange) and the errors specify operands, despite showing the _opcodes_ (which is what threw me off). +1.
paxdiablo
Turns out the first `la` probably _did_ have the error. It was misspelled `ls` in the original question and the error output wasn't updated properly when that was changed (`ls` error was deleted but `la` error wasn't put in, I'd guess). I've modified the question to insert the actual error output for that changed line as well (so the question makes more sense).
paxdiablo