Linux 提示用户输入组件ci20 seg故障
我目前正在ci20机器上开发一个小程序,提示用户输入整数值,然后将数值打印到屏幕上 我当前的代码Linux 提示用户输入组件ci20 seg故障,linux,assembly,mips,system-calls,ci20,Linux,Assembly,Mips,System Calls,Ci20,我目前正在ci20机器上开发一个小程序,提示用户输入整数值,然后将数值打印到屏幕上 我当前的代码 .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
.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故障,不知道为什么。如有任何帮助或建议,将不胜感激 编辑:出于某种原因,我完全忽略了在ci20机器上测试的这段代码 这是linux吗?然后你不能使用MARS系统调用,你必须找到linux系统调用。然后,它可能会在第一条
syscall
指令上执行segfaulting,因为参数对于Linux无效
要显示“prompt”,使用参数设置为
v0=4,a0=prompt
…的syscall
。。。要显示“message”,您可以将syscall的参数设置为v0=1,a0=message
如果是in,那么v0
=1是“打印整数”,因此a0
应该是整数,而不是“消息”字符串的地址。。您可能希望调用syscall两次,其中v0
=4和v0
=1(参数a0
为“消息”,用户为特定调用的整数)
无论如何,这些都不应该是错误的。segfault可能发生在代码末尾,代码结尾为addiu$sp,$sp,+4
,没有返回到ra
,或者调用syscall“exit”函数(从代码开头保存ra
,看起来您希望返回而不是退出,但这取决于您)。因此,在一些随机指令(未初始化的内存内容)上继续执行
无论如何,2,您应该弄清楚如何在调试器中加载此代码,并一条指令一条指令地跳过它,然后您将能够说出它在哪里发生故障,以及在指令发生故障之前寄存器的内容是什么。如果你的代码出错了,你甚至不知道在哪里,这表明你缺乏努力
(免责声明:我从未做过MIPS组装,所以我主要猜测它是如何工作的,可能忽略了一些东西)
编辑about
syscall
,也许这个提示也会有帮助
syscall
并不是什么神奇的指令,它在CPU上完成了所有漂亮的事情。它只是跳转到某个处理程序例程
该处理程序代码由操作系统设置。SO上的大多数MIPS程序集列表都是针对MARS或SPIM的,它们的处理程序与Linux完全不同
因此,您应该学习用于MIPS的LinuxABI,以及在那里如何使用syscall。然后找到linux系统调用表,您可能会找到大量x86文档,所以您必须将其转换为v0/a0/。。。阿比
您仍然可以遵循MARS的示例,但任何操作系统交互都必须进行调整,不要期望为所有操作系统找到替代方案。例如,输出数字在linux中不可用。您必须自己将数字值转换为ASCII字符串(对于单个数字,加上“0”就足够了,对于9以上的数字,您必须计算10的每一次幂的数字,并将其转换为ASCII字符并存储到某个缓冲区),然后使用sys_write/etc输出字符串。(或者链接一些libc并调用C库中类似sprintf的函数)。编辑:出于某种原因,我完全忽略了在ci20机器上测试的这段代码 那么这是linux吗?那么你不能使用MARS系统调用,你必须找到linux系统调用。它可能会在第一条
syscall
指令上出错,因为参数对linux无效
要显示“提示”,您使用参数设置为
v0=4,a0=prompt
的syscall
。要显示“消息”,您将syscall的参数设置为v0=1,a0=message
如果这是in,那么v0
=1是“打印整数”,因此a0
应该是整数,而不是“消息”字符串的地址……您可能需要调用syscall两次,其中v0
=4和v0
=1(参数a0
是“消息”并且用户是特定调用的整数)
无论如何,这一切都不应该发生segfault。segfault可能发生在代码末尾,代码以addiu$sp,$sp,+4
结尾,不返回ra
,也不调用syscall“exit”函数(从代码开头保存ra
,看起来您希望返回而不是退出,但这取决于您)。因此,在一些随机指令(未初始化的内存内容)上继续执行
无论如何,2,您应该知道如何在调试器中加载此代码,并逐条指令对其进行检查,然后您将能够说出它在哪里发生故障,以及在指令发生故障之前寄存器的内容。如果您的代码发生故障,而您甚至不知道发生故障的位置,则表明您在si上缺乏努力德
(免责声明:我从未做过MIPS组装,所以我主要猜测它是如何工作的,可能忽略了一些东西)
编辑about
syscall
,也许这个提示也会有帮助
syscall
并不是一条神奇的指令,它在CPU上完成所有漂亮的事情。它只是跳转到一些处理程序例程
该处理程序代码由操作系统设置。SO上的大多数MIPS程序集列表都是针对MARS或SPIM的,它们的处理程序与Linux完全不同
所以您应该研究MIPS的linux ABI,以及在那里如何使用syscall。然后找到linux系统调用表,您可能会找到大量x86文档,所以您必须将其转换为v0/a0/…ABI
您仍然可以遵循MARS示例,但任何操作系统交互都必须进行调整,不要期望找到替代方案。例如,输出数字在linux中不可用。您必须自己将数字值转换为ASCII字符串(对于单个数字,添加“0”就足够了,对于9以上的数字,必须计算10的每一次幂的数字,并将其转换为ASCI