我目前正在MIPS-Assembler中写一些东西,我遇到了一些麻烦: 我写了这个函数:
git config --global core.autocrlf input
如果我运行这个程序,指令添加$ a1,$ s0,$ 0被跳过,我不知道为什么......
另一个有趣的事情,如果我用GDB调试这个程序:
PRINT_FLOAT:
addi $sp, $sp, -4 #stackpointer um ein wort weiterrücken
sw $ra, 0($sp) #rücksprungadresse auf stack speichern
la $a0, strFloat
add $a1, $s0, $zero
jal printf
lw $ra, 0($sp) #rücksprungadresse aus stack holen
addi $sp, $sp, 4 #stackpointer um ein wort zurückrücken
jr $ra
并在main处设置断点,断点设置在第三个" addi $ t0,$ zero,3" 这里发生了什么?
答案 0 :(得分:1)
gdb
是一个高级源调试器,因此在逐个指令的基础上处理asm会有点困难。
例如,要逐步执行C代码,通常是" s"使用[step]命令。但是,gdb
将跨越"任何asm序列,它认为它是单个C语句的一部分。
要逐步执行个人asm说明,您需要" si" [步骤说明]命令。见help si
同样,在设置断点时,您希望使用修改后的命令形式。 break * whatever
在地址 whatever
设置断点。见help break
为了能够获得正确的地址,您可能需要反汇编一下,所以请参阅help disassemble
和help x
。要反汇编单个指令,x/i ...
也可以。
正如dwelch指出的那样,你的装配工可能会变得可爱"并重新排序。通过gdb
进行反汇编,您将能够看到是否发生了这种情况。并且,如果在实际处理器上启用/激活分支延迟时隙 ,则您需要对其进行说明。例如,当使用spim
或mars
等模拟器运行时,分支延迟槽的使用是可配置的[并且默认关闭],但是对于真正的处理器,可能没有选择。
如果我运行这个程序,指令添加$ a1,$ s0,$ 0被跳过,我不知道为什么......
这可能是您认为正在跳过add $a1,$s0,$zero
指令的原因。 gdb
[使用" step"]会将以下内容视为一个块:
la $a0,strFloat
add $a1,$s0,$zero
jal printf
断点设置在第三个
addi $t0, $zero, 3
再一次,出于与上述相同的原因。使用断点命令的替代形式。
答案 1 :(得分:0)
在函数中设置断点并且没有可用的调试信息时,gdb会尝试在function prologue之后设置断点。
Gdb分析机器指令以检测序言。 “addi $ sp,$ sp,-4”看起来可能被认为是序幕(但我不是MIPS专家所以我可能错了)。
在汇编/链接时启用调试信息,gdb应该有关于可用帧的更多信息。
您也可以反汇编主(disas main)并设置断点到第一条指令的地址(如:break * 0xabcdef)而不是“break main”。