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?
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.
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.
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.
精彩评论