仅仅因为 Linux 做到了,就不是做某事的理由。我对使用内联汇编的使用/愿望感到困惑,但是是的,当然,有一些方法可以做到这一点,你可以很容易地弄清楚。如果您问这个问题,您还没有准备好编写操作系统。继续努力。在开始之前,您需要 C 和工具基础知识。操作系统本质上是一个大型裸机程序。
如果您标记了这个 nasm,那么您无论如何都对内联 asm 不感兴趣,只需使用真正的 asm gas 或 nasm。
这个
int fun ( void )
{
return 5;
}
会/可以变成:
0000000000000000 <fun>:
0: b8 05 00 00 00 mov $0x5,%eax
5: c3
这意味着我可以做到这一点
.globl fun
fun:
mov $0x5,%eax
retq
还有这个
#include <stdio.h>
int fun ( void );
int main ( void )
{
printf("%d\n",fun());
return 0;
}
并构建一个二进制链接两个部分,运行时打印 5。
那么有了 nasm 我就可以了
global fun
fun:
mov eax,5
ret
在这种情况下确认它是相同的机器代码或至少是等效的。
0000000000000000 <fun>:
0: b8 05 00 00 00 mov $0x5,%eax
5: c3 retq
所以我可以链接它,它也会打印 5。
所以现在我可以做一个简单的内联,非常真实的 asm,也许你在问什么
#include <stdio.h>
int fun ( void );
asm(".globl fun ; fun: mov $0x5,%eax ; retq");
int main ( void )
{
printf("%d\n",fun());
return 0;
}
这是使用 gcc,内联 asm 是特定于工具的,不假定是可移植的。
现在你可以从那里严重过度复杂化。
在操作系统(或任何地方)中使用抽象来执行 I/O 操作(“它基本上将字节 x 写入端口 y”)绝对是正确的做法(您不想内联类似的东西),因此,一个单独的函数,无论是真正的 asm、C 还是某种混合函数,都是值得追求的好主意。归根结底,对于像这样的访问类型功能,您需要完全控制所使用的指令,因此您选择这样做取决于您。但是在开始这样的任何工作之前,需要对工具和语言的基本使用。您可以检查现在存在的不同操作系统作为参考,但这不是您的,不是他们的,您的个人偏好不是其他人的,您对语言和工具和假设的了解不是其他人的。他们可能有一个系统级的实现,你可能看不到所有的东西,并且可以通过简单地在这里或那里复制一个片段而陷入陷阱。