提示用户inputassemblyci20 seg故障

我目前正在一个ci20机器上的小程序,提示用户input一个整数值,然后将值打印到屏幕上。

我目前的代码

.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 

当我尝试运行程序时,我得到一个seg故障,不知道为什么。 任何帮助或build议将不胜感激。

编辑:由于某种原因,我完全忽略了这个代码在ci20机器上进行了测试。

那么这个Linux? 那么你不能使用MARS系统调用,你必须找到linux系统调用。 那么可能会在第一个syscall指令中进行segfaulting,因为参数对于Linux是无效的。


要显示“提示符”,使用参数设置为v0 = 4, a0 = prompt syscall v0 = 4, a0 = prompt …要显示“消息”,请将系统调用的参数设置为v0 = 1, a0 = message

如果这是在MARS中 ,那么v0 = 1是“打印整数”,所以a0应该是整数,而不是“消息”字符串的地址。 你可能想调用系统调用两次, v0 = 4和v0 = 1(参数a0是“消息”,用户整数特定的调用)。

无论如何,这不应该segfault。 segfault可能发生在最后,代码以addiu $sp, $sp, +4结尾,而不是返回到ra ,或者调用syscall“exit”函数(从代码开始处的ra的保存开始)就像你想要退出而不是退出,但这取决于你)。 所以执行继续一些随机指令(未初始化的内存内容)。

无论如何2,你应该弄清楚如何在调试器中加载这段代码 ,然后按照指令逐步执行它 ,然后你将能够说出段错误的位置,以及段错误指令之前寄存器的内容是什么。 如果你的代码段错误,你甚至不知道在哪里,它显示在你身边缺乏努力。

(免责声明:我从来没有做MIPS汇编,所以我主要猜测它是如何工作的,可能忽略了一些东西)


编辑关于syscall ,也许这个提示也会有帮助?

syscall是不是一些神奇的指令做CPU的所有漂亮的东西。 它只是跳转到一些处理程序。

该处理程序代码由OS设置。 SO上的大多数MIPS汇编列表都针对MARS或SPIM,它们与Linux完全不同。

所以你应该研究MIPS的linux ABI,以及如何使用系统调用。 然后找到linux系统调用表,你可能会发现吨的x86文件,所以你必须转换成v0 / a0 / … ABI。

你仍然可以遵循MARS的例子,但任何操作系统的交互都必须调整,不要指望找到替代的一切。 例如输出数字在Linux中不可用。 您必须自己将数字值转换为ASCII字符串(对于单个数字的数字,加上'0'就足够了,对于9以上的数字,您必须计算每个10的幂的数字,并将其转换为ASCII字符并将其存储到某个缓冲区),然后用sys_write / etc输出字符串。 (或者链接一些libc并从C库中调用sprintf的函数)。