调试机器级程序

2024年8月28日 | 阅读 4 分钟

调试过程用于查找和删除程序或软件中的错误。在此过程中,将在执行、机器码和程序逻辑中识别出错误。在这里,借助与代码执行相关的逐步信息来识别程序中的故障。

调试机器码

借助原理图构建电路和将汇编语言转换为机器码是同一件事。借助调试,我们能够确定以下内容

  • 程序流程
  • 代码循环
  • 寄存器的值
  • 进入 if 或 else 语句
  • 计算检查
  • 函数的入口和出口点

以下描述了一些常见的错误来源

  • 选择错误代码。
  • 指定不正确的跳转位置。
  • 用十进制代替十六进制,写下内存地址。
  • 在跳转指令上,如果我们指定了不正确的内存地址。
  • 如果我们未能清除进位寄存器。
  • 如果我们忘记指令的第二个或第三个字节。
  • 在跳转指令之前,如果我们忘记设置标志。
  • 当我们添加两个数字并且未能清除累加器时。
  • 如果我们使用了不当的旋转指令组合。
  • 在跳转指令期间,如果我们没有颠倒高字节和低字节的顺序。

调试过程基本上分为两个部分,如下所述

静态调试

这种调试与对电路板的视觉检查相同。在这种调试中,我们只拿一张纸和一支笔,尝试在机器码和流程图中查找错误。借助静态调试很难捕获一些代码错误。在这里,我们只是尝试理解程序的结构和代码逻辑,以便我们能够找到并删除错误。

在详尽的情况下,错误会随机弹出。错误大多出现在重用和扩展代码的情况下。当错误显现时,我们尝试借助逐步执行测试用例并尝试调试会话来重现该问题。有时我们的运气很好,并且我们很容易重现问题。假设我们想确定某种组合,以便我们可以触发域效应,因此错误会显现出来。在这种情况下,该过程可能需要数小时甚至数天的努力。借助静态调试,我们能够更快、更主动地找出问题区域。

动态调试

在这种调试中,借助单步技术,或者借助断点技术,在每条指令执行后观察寄存器的数据或输出,或者在执行一组指令后观察寄存器的数据或输出。单板微处理器的工具和技术通常使用动态调试。这些工具和技术描述如下

1. 单步执行

在这种技术中,我们一次只能执行一条指令。在这里,我们基本上观察每条指令的输出。借助硬件逻辑电路构建此技术。仅当我们按下单步运行键时,我们才会观察内存位置和寄存器的数据。由于这个键,我们将能够发现以下内容

  • 不正确的地址
  • 丢失代码或不正确的数据
  • 循环中的不正确的跳转位置

对于大型循环,这种调试非常耗时和令人疲倦。因此,我们可以通过减少迭代次数而不是循环 n 次来检查循环的有效性。对于短程序,非常有用的技术是单步技术。

2. 断点

软件例程和断点设施彼此类似。由于断点,我们能够分段执行程序。借助 RST 指令,可以设置断点。按下执行键后,程序将执行到断点。可以借助寄存器检查预期结果。假设我们借助断点设施隔离了程序中包含错误的片段。之后,我们可以使用单步设施来调试该片段。它可用于检查以下内容

  • 中断
  • 定时循环
  • I/O 部分

动态断点是用户特定的。当我们的程序到达异常类或特定语句时,此时将触发断点。当用户注销时,断点将自动删除。我们总共能够设置 30 个动态断点,而无需更改源代码。此断点可以在运行时创建、删除或停用。如果程序被其他用户锁定,我们甚至可以为该程序设置动态断点。

3. 寄存器检查

借助寄存器检查键,我们能够检查微处理器寄存器的内容。我们可以将此技术与分解设施或单步设施结合使用。