3

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?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Nathan Campos
  • 28,769
  • 59
  • 194
  • 300
  • could you see my question here http://stackoverflow.com/questions/9403667/mips-hex-output/9403758#comment11954218_9403758 and provide a response as to what the process is for turning a .s assembly file as you have above to an object file? Thanks – NickHalden Feb 26 '12 at 05:41

3 Answers3

4

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
  • 854,327
  • 234
  • 1,573
  • 1,953
  • Sorry about the `ls`, it was just my mistake. – Nathan Campos Jan 28 '10 at 02:46
  • If I try to change, I just got more `illegal operands` error, but now with `lui` and `ori`. – Nathan Campos Jan 28 '10 at 02:49
  • Take a look on the page of that book, the code is like that. Now I've copied and pasted. – Nathan Campos Jan 28 '10 at 02:53
  • 1
    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 Jan 28 '10 at 03:04
  • Thanks for the help mate. I'm going to wait for someone that can help me on this. – Nathan Campos Jan 28 '10 at 16:42
3

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.

Community
  • 1
  • 1
Matthew Slattery
  • 45,290
  • 8
  • 103
  • 119
  • 1
    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 Jan 28 '10 at 23:30
  • 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 Feb 01 '10 at 10:52
0

I think it is your sequence of listing of li and la, unless you load an address, you can't load immediate and tell $v0 to hold on to the string you want to appear.. try putting the la first before li in each case... well as for pseudo instructions, yes, that can be the problem as well, but my suggestion is worth a try.

ronalchn
  • 12,225
  • 10
  • 51
  • 61