x64 计算向前跳跃

x64 calculating forward jumps

如果你有一条向前跳转的指令,有没有办法计算偏移地址,或者你只是在第二次传递时计算绝对跳转?

像这样:

Jump to Label
Move 0 to 64bit Register 1
Label:
Move 0 to 64bit Register 2

在这种情况下,编译器是否只使用绝对跳转?我的意思是可以在像这样的简单情况下计算偏移量,但是随着标签的增加,它的成本呈指数级增长,更不用说相互嵌套的跳转和标签了...

这是一个很好的问题,但并不难解决。解决方案是不使用绝对跳跃——这甚至不能解决任何问题。你必须知道目标的地址,如果你知道你可能也知道当前地址并且你可以进行相对跳转。所以这是一个死胡同。

一个简单的解决方案是对代码进行两遍(或"one and a half"),在第一遍中您收集所有地址(您不能发出代码,因为此时您不对前向引用一无所知),在第二遍中,您使用此信息发出所有带有分支和所有内容的代码。 "One and a half" pass 发出分支的代码和占位符,然后返回以填充分支的偏移量。这避免了再次解析。

但是这有一个问题,第一遍无法决定是否可以使用短跳转或普通跳转,因此它实际上无法知道代码大小。但这可能需要猜测,然后您可以通过用更宽的分支替换该分支来迭代地修复每个引用其范围之外的标签的分支。你也可以反过来,从完整的跳跃开始,然后尝试用更短的跳跃来代替它们。