Assembly 为什么程序集调用地址中添加了0xFBFFFFFF?

Assembly 为什么程序集调用地址中添加了0xFBFFFFFF?,assembly,call,object-code,Assembly,Call,Object Code,好的,我正在为我正在开发的操作系统编写汇编程序。很好,我已经掌握了所有mov指令,现在我想实现call和jmp等指令。我真的没有好的文档,所以我正在查看NASM生成的机器代码,以找出操作码等。我想看看call的操作码是什么,所以我编译了一些代码,这些代码是从begging的标签开始的。我希望呼叫操作码后的地址是00,但它是FB FF FF。我认为这与符号有关,所以我使用调用0x000000编译代码,以查看发生了什么,地址完全相同(0xFBFFFFFF)。有人能给我解释一下吗?我很困惑。call通

好的,我正在为我正在开发的操作系统编写汇编程序。很好,我已经掌握了所有mov指令,现在我想实现call和jmp等指令。我真的没有好的文档,所以我正在查看NASM生成的机器代码,以找出操作码等。我想看看call的操作码是什么,所以我编译了一些代码,这些代码是从begging的标签开始的。我希望呼叫操作码后的地址是00,但它是FB FF FF。我认为这与符号有关,所以我使用调用0x000000编译代码,以查看发生了什么,地址完全相同(0xFBFFFFFF)。有人能给我解释一下吗?我很困惑。

call
通常有多种形式,例如,一种是使用绝对地址跳转到的,另一种是相对于当前地址跳转的。这可能是相对的,尽管四个字节可能不是直接的偏移量


如果有疑问,尤其是在实现汇编程序时,您可能需要查看手册或数据表。

调用通常以各种形式出现,例如使用绝对地址跳转到的调用,相对于当前地址跳转的调用。这可能是相对的,尽管四个字节可能不是直接的偏移量


如果有疑问,尤其是在实现汇编程序时,您可能需要查看手册或数据表。

显示您正在反汇编的实际代码将非常有用。最有可能的数字是一个小的endian负偏移量。0xFFFFFB=-5英寸2秒补码。你写过:

Label: call Label

如果调用是一个1字节的操作码,带有4字节的相对偏移量,这将是有意义的。

显示正在反汇编的实际代码将非常有用。最有可能的数字是一个小的endian负偏移量。0xFFFFFB=-5英寸2秒补码。你写过:

Label: call Label

如果调用是具有4字节相对偏移量的1字节操作码,则有意义。

32位用户模式x86代码中最常见的调用形式是
调用rel32
,它“调用”操作数处的一个点加上下一条指令的地址。这是一个近亲电话

作为参考,可以使用绝对调用,但编码是6字节而不是5字节;编码将是
FF 14 XX XX XX XX
。额外的字节(
14
)告诉指令读取将用作立即数的立即数位移。但是,这需要根据加载程序的模块库进行重写;重新定位时,不需要注意相对呼叫

在执行指令时,要可视化其工作方式,请执行以下操作:

  • EIP
    (指令指针)递增以指向下一条指令
  • 该地址被推送到堆栈上(以提供返回地址)
  • 立即数(如rel32值)被添加到
    EIP
    ,并且
  • 下一条指令正常地从(新的)
    [EIP]
    读取
当对该指令进行编码时,它看起来是这样的:
E8 XX XX XX
。由此可以看出,指令的长度为5字节

由于
EIP
随指令长度递增,因此调用将相对于指令开始后的点5字节。因此,如果调用0x00000000指令的相对地址恰好是0x00000000,则需要从
EIP
中减去5;汇编程序已将绝对地址转换为相对地址

偏移量可以是负数。另外,请记住x86地址是小端。因此,指令是
E8 FB FF


有趣的是,此特定指令的结果是,
EIP+5
将持续推送到堆栈上,直到生成异常(
#SS(0)
)为止。

32位用户模式x86代码中最常见的调用形式是
调用rel32
,它“调用”插入操作数加上下一条指令地址的一个点。这是一个近亲电话

作为参考,可以使用绝对调用,但编码是6字节而不是5字节;编码将是
FF 14 XX XX XX XX
。额外的字节(
14
)告诉指令读取将用作立即数的立即数位移。但是,这需要根据加载程序的模块库进行重写;重新定位时,不需要注意相对呼叫

在执行指令时,要可视化其工作方式,请执行以下操作:

  • EIP
    (指令指针)递增以指向下一条指令
  • 该地址被推送到堆栈上(以提供返回地址)
  • 立即数(如rel32值)被添加到
    EIP
    ,并且
  • 下一条指令正常地从(新的)
    [EIP]
    读取
当对该指令进行编码时,它看起来是这样的:
E8 XX XX XX
。由此可以看出,指令的长度为5字节

由于
EIP
随指令长度递增,因此调用将相对于指令开始后的点5字节。因此,如果调用0x00000000指令的相对地址恰好是0x00000000,则需要从
EIP
中减去5;汇编程序已将绝对地址转换为相对地址

偏移量可以是负数。另外,请记住x86地址是小端。因此,指令是
E8 FB FF

有趣的是,这条特殊指令的结果是,
EIP+5
将持续推送到堆栈上,直到生成异常(
#SS(0)
)。

aaaaah,忘了小endian