【问题标题】:How did an assember for x86 get a label's address defined after jmp instructions referenced to it?x86 的汇编程序如何获得在引用它的 jmp 指令之后定义的标签地址?
【发布时间】:2014-12-18 17:36:04
【问题描述】:

例如:

jmp LABEL

...  # loads of instructions

jmp LABEL

.... # loads of instructions

LABEL:

.....

没有jmp LABEL指令的大小,无法确定LABEL的地址,因为jmp指令的两种形式(short(2字节),near(3或5字节))大小不同。然而,在不知道 LABEL 的地址的情况下,您无法确定使用哪种形式。

汇编是怎么解决的?

【问题讨论】:

  • 从逻辑上讲,汇编代码是一个多阶段的操作。在生成所有其他代码之前,不会解析标签的地址。所以jmpLABEL之间的所有编码指令的大小都是已知的。

标签: assembly x86


【解决方案1】:

这取决于您使用的汇编器类型。一个简单的 2-pass 汇编器(如 MASM)会成为您的问题。他们会选择跳远,您必须明确写JMP SHORT LABEL 才能获得短跳。猜错了就骂你。

优化的 n-pass 汇编器(如 TASM)会自行对其进行排序。它采用短跳转,如果发现无法到达,则重新启动程序集,现在进行长跳转。

您可以轻松分辨出您的口味。看看它生成的代码清单,如果你得到了 5 字节的长跳转,那么你就有了 2-pass 类型。

【讨论】:

  • 旧版本的nasm 过去总是使用长的jmp,而yasm 足够聪明,可以使用短的jmp - 尽管nasm 现在可能会更好。
  • 不要忘记 FASM,它是有史以来最先进的多通道汇编程序。它总是生成尽可能小的操作码。
【解决方案2】:

您始终可以使用 5 个字节(操作码 + 远地址),所以这是汇编程序最初所做的。 然后它运行(可能多次)减少算法,看看它是否可以改进代码。一旦它发现没有改进的可能,它就会停止并完成代码。

【讨论】:

    猜你喜欢
    • 2010-09-17
    • 1970-01-01
    • 2019-03-17
    • 2015-10-27
    • 1970-01-01
    • 1970-01-01
    • 2011-02-18
    • 1970-01-01
    相关资源
    最近更新 更多