我目前正在一个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,5 syscall # get user input move $t0,$v0 # save input in $t0 move $a0,$v0 addi $v0,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,+4 # release the stack space used for $sp
当我尝试运行程序时,我得到一个seg故障,不知道为什么。 任何帮助或build议将不胜感激。
如何反汇编原始x86代码?
PE文件操作码
Linux汇编:“testingeax,eax”和“cmp eax,0”有什么区别
堆利用失败:内存损坏
在未初始化的局部variables的情况下,Windows线程堆栈守护页机制如何工作?
为什么PE需要Original First Thunk(OFT)?
修改程序我不是所有者
将数组传递给x86 asm中的函数
编辑:由于某种原因,我完全忽略了这个代码在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,+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的函数)。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。