Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 如何对给定的32位地址进行far(x86)调用?_Assembly_X86 - Fatal编程技术网

Assembly 如何对给定的32位地址进行far(x86)调用?

Assembly 如何对给定的32位地址进行far(x86)调用?,assembly,x86,Assembly,X86,好的,我需要执行对PCI BIOS服务目录(32位模式)的调用,以验证PCI BIOS是否存在 注意:我正在为一个简单的操作系统开发一个简单的磁盘驱动程序,我们正在开发一个学院。我知道这是非常具体的,但我将从内核代码中完成所有这些 假设我已经找到了相关的地址。对给定地址执行远端调用的正确汇编语言是什么?有人可以发布一些汇编代码,对给定的32位地址进行远端调用吗?到目前为止,我看到的示例的语法令人困惑 谢谢 编辑:在我的特定情况下,我已经找到了PCI BIOS服务目录,它为我提供了物理地址(32位

好的,我需要执行对PCI BIOS服务目录(32位模式)的调用,以验证PCI BIOS是否存在

注意:我正在为一个简单的操作系统开发一个简单的磁盘驱动程序,我们正在开发一个学院。我知道这是非常具体的,但我将从内核代码中完成所有这些

假设我已经找到了相关的地址。对给定地址执行远端调用的正确汇编语言是什么?有人可以发布一些汇编代码,对给定的32位地址进行远端调用吗?到目前为止,我看到的示例的语法令人困惑

谢谢

编辑:在我的特定情况下,我已经找到了PCI BIOS服务目录,它为我提供了物理地址(32位)。给定这个32位地址,我需要什么类型的远端呼叫?例如,我在英特尔手册中读到,far调用可以改变任务,什么都可以。我如何知道我必须做些什么才能远调用此PCI BIOS服务目录物理地址

更新:

以下是我发现的一些让我困惑的代码(内联):

asm(“lcall(%%edi)”
:“=a”(返回代码),
“=b”(地址),
“=c”(长度),
“=d”(条目)
:“0”(服务),
"1" (0),
“D”(&bios32_间接))

我在这个源文件中发现:


我想我要做的是在实际汇编中等效于上面的内联。

如果内存是扁平的,即CS的基数为0,并覆盖整个32位地址空间

call <address>
呼叫
其中address是32位目标地址

编辑:啊,我看到你有一个实际地址。我想这是针对Linux上运行的设备驱动程序的。我对linux内核没有任何经验,但我认为这个物理地址没有1:1映射到虚拟地址。您需要将它映射到一个虚拟地址(对不起,在Linux中不知道如何映射),然后调用该虚拟地址

但这就提出了一个问题,即您需要什么样的PCI BIOS功能,直接进入操作系统之外的BIOS通常是错误的方法

从手册中:

to make a asm call use the below format

asm(  command1 %0
      command2
      :output registers with there mapping to variable
      :input registers with mapping.
   );

example
    asm ("movl %1, %%ebx;"
         "movl %%ebx, %0;"
         : "=r" ( val )
         : "r" ( no )
         : "%ebx"         // clobbered register
        );

    here %1 is input variable %0 is output.
要生成
lcall
,需要段和实际32位地址:

bios32_indirect.address = directoy_address;
  uint32 kernelcodesegment = 0;
  asm ("movl %%cs, %0;"
       : "=r" (kernelcodesegment)
       :);
bios32_indirect.segment = kernelcodesegment;

如果您提到您正在使用的操作系统,肯定会有所帮助。 假设它是Windows 32位,那么假设您确实知道物理地址,您仍然需要获取与它相关的PTE。您不能只调用该特定地址,因为您处于保护模式,并且您拥有的地址是虚拟地址。可以将物理映射到虚拟,但这很复杂

如果您想查看是否可以查看该地址上的内容,请使用WinDBG并执行以下操作:

!dd <address>
!dd
这将在指定的物理地址显示DWORD。 当您知道要做什么时,物理到虚拟的转换非常简单(查看CR3对您没有帮助:)

现在,如果您使用的是不同的操作系统,那么情况就不同了,因为PTE的映射方式不同

此外,正如前面提到的,您不能只调用bios,因为它实际上是16位而不是32位。 在受保护模式下(在i386和可能更高版本中),有一种特定的技术可以使用vx86或类似的东西,但我忘记了确切的术语。这是可行的,但成本非常高,因为它涉及任务切换和其他杂项


如果您需要开发磁盘驱动程序,那么您团队中的硬件人员应该能够为您提供可用的端口,以便您可以对设备进行IO调用,从而消除访问BIOS的需要。

如果您公布了他们的困惑,这会有所帮助。通话应该正常。但这不就是执行近距离通话吗?例如,我认为您必须更改CS注册表。您提到了32位模式,它通常意味着一个平坦的地址空间,描述符覆盖整个4GB。那你为什么要换CS呢?你真的想做跨段通话还是只想做32位通话?呼叫可以跳转到任何32位地址。Mihai-您可以在32位模式下进行分段。没有人真的知道。啊,我应该更详细地说。我们正在研究一个在大学里开发的简单操作系统。我的任务是开发一个简单的磁盘驱动程序。
!dd <address>