我正在尝试分析几年前使用IDA Free 5.0编写的MS-DOS COM文件,此后我将该段重命名为code_and_data,并命名了常量并正确设置了数据类型。但是,在查看反汇编时,清单中显示了db伪指令,如下所示: db和它之后的cmp指令从同一地址开始(请参见左列)。为什么IDA会显示/添加这些db伪指令?同一段既用于代码又用于数据,它会尝试“有帮助”并同时将代码显示为数据)?

但是如果这样,为什么它只显示指令的第一个字节(如果再次查看左侧的地址,则这些指令的长度超过1个字节)。

评论

db语句不是反编译器说“我无法理解的,对吗?”的方式?

#1 楼

字节3Eh是段替代DS:的编码。您在类似

cmp     byte ptr ds:3BEh, 'C'


的指令中观察到了该指令的十六进制编码是(我手动执行此操作,可能有些错误)

3E    - segement override prefix
80    - 8 bit ALU instruction
3E    - mod/rm byte (reg = 7 -> instruction is CMP, mod = 0/rm = 6 -> immediate address)
BE 03 - offset of data to compare
43    - immediate data byte


序列3E 80 3E BE 03 53长6个字节,与6个字节的实际指令长度(010Eh - 0108h)相匹配。如果您使用标准x86汇编程序(如MASM)汇编IDA提供的汇编程序源代码,则将省略DS:前缀,因为默认情况下寻址模式“立即地址”相对于数据段。 IDA显示了额外的DB指令,以告诉您(或尝试重新汇编清单的汇编程序)冗余的多余段前缀实际上是用二进制编码的。如果要隐藏该信息,请选中选项->常规->分析->“特定于处理器的分析选项”->“不显示冗余指令前缀”。

评论


谢谢,这真的很详细。您指定的指令的十六进制编码与我的输入文件中的相同。而该选项正是我一直在寻找的,启用该选项确实可以隐藏清单中的db伪指令。凉!

– Thomas Perl
17年8月25日在18:35

#2 楼

编辑:感谢迈克尔的澄清,这些不是分支提示,而是段前缀。保留答案,以供参考以及来自搜索引擎的人员使用。


这些是“分支提示”,旨在为处理器提供有关是否可能发生分支的“提示”。

分支预测

它用于优化,称为分支预测-处理器进行的一种尝试,用于预测代码将采用哪个分支。 CPU可以通过在解决条件之前对分支的方向进行假设来保持处理。否则,它正在“坐着”,并等待分支所依赖的条件得以解决。

来自维基百科:


在计算机体系结构中,分支预测器是
数字电路,它试图猜测分支的方向(例如,
if-then-else结构)将在确定之前就消失了。分支预测器的
目的是改善
指令管道中的流程。分支预测器在
在许多现代流水线微处理器体系结构(例如x86)中实现高效性能中起着至关重要的作用。


分支提示

>您可以通过使用在条件跳转指令之前插入的提示字节来暗示CPU采取分支的可能性。
通过在条件跳转之前插入的跳转提示字节来完成此操作。指令。

字节分别是3Eh2Eh,它们的含义如下:


2Eh-暗示分支不会在大多数时间出现。 3Eh-暗示分支将在大多数时间发生。


更多信息:

您可以在此处(推荐)和此处阅读有关分支提示和优化的更多信息。
如果您想了解有关分支预测的更多信息,我建议您阅读有关动态分支预测的文章。

评论


有意义,谢谢您-我知道避免GLib的G_LIKELY()/ G_UNLIKELY()宏产生分支错误预测的概念,有趣的是,分支提示已经存在了很长时间。那么IDA的缺点是不会为那些IDA生成伪程序集吗?

– Thomas Perl
17年8月25日在13:53



被否决的原因是这个答案错过了问题。 2Eh和3Eh仅在跳转指令的前缀时用作分支提示。在这种情况下,它们为存储指令加前缀并以原始方式工作-即作为段前缀。

– Michael Karcher
17年8月25日在18:16