Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 汇编程序-跳过指令_Assembly_Gdb_Mips_Skip - Fatal编程技术网

Assembly 汇编程序-跳过指令

Assembly 汇编程序-跳过指令,assembly,gdb,mips,skip,Assembly,Gdb,Mips,Skip,我目前正在MIPS Assembler中编写一些东西,遇到了一些问题: 我写了这个函数: 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, $z

我目前正在MIPS Assembler中编写一些东西,遇到了一些问题: 我写了这个函数:

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
如果我运行这个程序,将跳过指令add$a1、$s0、$zero,我不知道为什么

另一件有趣的事,如果我用GDB调试这个程序:

  main:

        addi $t0, $zero, 3
        addi $t0, $zero, 3
        addi $t0, $zero, 3
        jal READ_FLOAT

        jal PRINT_FLOAT
并在main处设置断点,断点设置在第三个“addi$t0,$zero,3”
这里发生了什么?

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

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

要单步执行单个asm指令,需要使用“si”[step指令]命令。请参阅帮助si

同样,在设置断点时,您希望使用修改后的命令形式
break*which
在地址
which
设置断点。请参见帮助中断

为了能够获得正确的地址,您可能需要进行一些反汇编,因此请参阅
帮助反汇编
帮助x
。要反汇编单个指令,
x/i…
也可以工作

正如德韦尔奇指出的,你的汇编程序可能会“变得可爱”并重新排序。通过让
gdb
进行反汇编,您将能够看到是否发生了这种情况。而且,如果在实际处理器上启用/激活了分支延迟插槽,则需要考虑它们。例如,当使用诸如
spim
mars
之类的模拟器运行时,分支延迟槽的使用是可配置的[并且默认为关闭],但对于真正的处理器,可能没有选择

如果我运行这个程序,将跳过指令add$a1、$s0、$zero,我不知道为什么

这可能就是您认为
add$a1、$s0、$zero
指令被跳过的原因<代码>gdb[带“步骤”]将以下内容视为单个块:

    la      $a0,strFloat
    add     $a1,$s0,$zero
    jal     printf
断点设置在第三个
addi$t0、$0、3


同样,出于与上述相同的原因。使用breakpoint命令的另一种形式。

当您在函数中设置断点,并且没有可用的调试信息时,gdb会尝试在一个断点之后设置断点

Gdb分析机器指令以检测序言。“addi$sp,$sp,-4”看起来像是开场白(但我不是MIPS专家,所以我可能错了)

在组装/链接时启用调试信息,gdb应该有关于可用帧的更多信息


您还可以反汇编main(disas main)并将断点设置为第一条指令的地址(如:break*0xabcdef),而不是“break main”。

您正在使用优化进行组装吗?这对于三个
addi
语句是有意义的,因为它们都做相同的事情,使得其中两个多余。您的汇编器是否将add放入分支延迟槽?您的反汇编对此代码显示了什么?以前你必须明确地做这件事,上次我使用gnu汇编程序时,它只是简单地将前面的指令与分支交换,必须明确地告诉它不要这样做。或者告诉它该体系结构没有分支延迟槽。基于MIPS disassemby,我回顾了“addi$sp,$sp,-4”将堆栈大小增加了4个字节。通常在函数“addi$sp,$sp,4”的末尾有一个补充行,以将堆栈减少相同的数量。