汇编程序 - 跳过说明

时间:2016-05-02 09:17:31

标签: assembly gdb mips skip

我目前正在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" 这里发生了什么?

2 个答案:

答案 0 :(得分:1)

gdb是一个高级源调试器,因此在逐个指令的基础上处理asm会有点困难。

例如,要逐步执行C代码,通常是" s"使用[step]命令。但是,gdb将跨越"任何asm序列,它认为它是单个C语句的一部分。

要逐步执行个人asm说明,您需要" si" [步骤说明]命令。见help si

同样,在设置断点时,您希望使用修改后的命令形式。 break * whatever地址 whatever设置断点。见help break

为了能够获得正确的地址,您可能需要反汇编一下,所以请参阅help disassemblehelp x。要反汇编单个指令,x/i ...也可以。

正如dwelch指出的那样,你的装配工可能会变得可爱"并重新排序。通过gdb进行反汇编,您将能够看到是否发生了这种情况。并且,如果在实际处理器上启用/激活分支延迟时隙 ,则您需要对其进行说明。例如,当使用spimmars等模拟器运行时,分支延迟槽的使用是可配置的[并且默认关闭],但是对于真正的处理器,可能没有选择。

  

如果我运行这个程序,指令添加$ 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”。