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