在程序集中提示用户输入ci20 seg fault

时间:2016-10-14 08:37:32

标签: 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

    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错误而不确定原因。任何帮助或建议将不胜感激。

1 个答案:

答案 0 :(得分:3)

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

这是linux吗?那么你不能使用MARS系统调用,你必须找到linux系统调用。然后可能会在第一条syscall指令上进行分区,因为参数对Linux无效。

显示"提示"您使用syscall并将参数设置为v0 = 4, a0 = prompt ...来显示" message"您将syscall的参数设置为v0 = 1, a0 = message

如果这是MARS,那么v0 = 1是"打印整数",所以a0应该是整数,而不是"消息& #34;串。 ..你可能想要两次调用系统调用,v0 = 4和v0 = 1(参数a0是"消息"和特定呼叫的用户整数)。

无论如何,这一切都不应该是段错误。段错误可能发生在最后,您的代码以addiu $sp, $sp, +4结束,不返回ra,或调用系统调用"退出"功能(在代码开头保存ra看起来你想要返回而不是退出,但它取决于你)。因此,执行会继续执行一些随机指令(未初始化的内存内容)。

无论如何2,你应该弄清楚如何在调试器中加载这段代码并按指令逐步执行,然后你就可以说出段落的确切位置,以及它的内容是什么在segfaulting指令之前注册。如果你的代码是段错误的,而你甚至不知道在哪里,那就表明你没有那么努力了。

(免责声明:我从未做过MIPS组装,所以我大多猜测它是如何工作的,可能忽略了一些东西)

编辑syscall,或许这个提示也有帮助吗?

syscall不是一些魔术指令在CPU上做所有那些漂亮的东西。它只是跳转到一些处理程序例程。

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

所以你应该研究Linux ABI for MIPS,以及如何在那里使用系统调用。然后找到linux系统调用表,你可能会找到大量的x86文档,所以你必须把它转换成v0 / a0 / ... ABI。

您仍然可以关注MARS示例,但必须调整任何操作系统互动,并且不要期望找到所有内容的替代方案。例如,输出数字在linux中不可用。您必须自己将数字值转换为ASCII字符串(对于单个数字的数字,添加' 0'就足够了,对于9以上的数字,您必须为每个10的幂计算数字并将其转换为ASCII字符和将它存储到某个缓冲区中,然后输出带有sys_write / etc的字符串。 (或链接一些libc并调用sprintf - 类似C库中的函数)。