I am currently working on a small program on a ci20 machine that prompt the user for a integer value then print the value to the screen.
My current code
.data
prompt:
.asciiz "Please enter an integer: "
message:
.asciiz "\nValue entered: "
.text
.global main
main:
addiu $sp, $sp, -4 # push stack
sw $ra, ($sp) # save return address
addi $v0, $0, 4
la $a0, prompt
syscall # printing prompt
addi $v0, $0, 5
syscall # get user input
move $t0, $v0 # save input in $t0
move $a0, $v0
addi $v0, $0, 1 # Not sure if this is right to print message
la $a0, message # Not sure if this is right to print message
syscall
lw $ra, ($sp) # restoring $sp
addiu $sp, $sp, +4 # release the stack space used for $sp
When I try to run the program I get a seg fault and not sure why. Any help or suggestion would be greatly appreciated.
edit: for some reason I completely ignored this code was tested on ci20 machine.
So is this linux? Then you can't use MARS syscalls, you have to find linux syscalls instead. It is then probably segfaulting on the very first
syscall
instruction, as the arguments are invalid for Linux.To display "prompt" you use
syscall
with arguments set asv0 = 4, a0 = prompt
... to display "message" you set arguments for syscall asv0 = 1, a0 = message
.If this is in MARS, then
v0
=1 is "print integer", soa0
should be integer, not address of "message" string. .. you probably want to call syscall twice, withv0
=4 andv0
=1 (argumenta0
being "message" and users integer for particular call).Anyway, none of this should segfault. The segfault happens probably at the end, where your code ends with
addiu $sp, $sp, +4
, not returning to thera
, or calling syscall "exit" function (from the saving ofra
at the start of your code it looks like you want rather to return than exit, but it's up to you). So the execution continues over some random instructions (uninitialized memory content).Anyway 2, you should figure out how to load this code in debugger and step over it instruction by instruction, then you will be capable to say where exactly it segfaults, and what was the content of registers before segfaulting instruction. If your code segfaults and you don't even know where, it shows lack of effort on your side.
(disclaimer: I never did MIPS assembly, so I'm mostly guessing how it works and may have overlooked something)
edit about
syscall
, maybe this hint will help too?syscall
isn't some magic instruction doing all that nifty stuff on the CPU. It just jumps to some handler routine.That handler code is set up by the OS. Most of the MIPS assembly listings on SO are targetted at MARS or SPIM, which have completely different handler than Linux.
So you should study linux ABI for MIPS, and how syscall is used there. And then find linux system calls table, you will probably find ton of x86 docs, so you have to convert that into v0/a0/... ABI.
You can still follow MARS examples, but any OS interaction has to be adjusted, and don't expect to find alternative for everything. For example outputting the number is not available in linux. You have to convert the number value into ASCII string by yourself (for single digit numbers adding '0' is enough, for numbers above 9 you have to calculate digit for each power of 10 and convert it into ASCII character and store it into some buffer), and output then the string with sys_write/etc. (or link with some libc and call
sprintf
-like function from C library).