【发布时间】:2019-10-26 08:08:37
【问题描述】:
以下代码我已读取用户输入,类似于C 语言中的gets 函数。
section .text
global _start
_start:
mov eax, 3 ; Read user input into str
mov ebx, 0 ; |
mov ecx, str ; | <- destination
mov edx, 100 ; | <- length
int 80h ; \
mov eax, 1 ; Return
mov ebx, 0 ; | <- return code
int 80h ; \
section .data
str: times 100 db 0 ; Allocate buffer of 100 bytes
我不确定 Linux 是如何处理我的代码的,但我很好奇这些代码是如何在英特尔机器上本地处理的(没有任何操作系统)。据我所知,通过中断向量表查找中断80h,并调用相关代码函数。但是,再低一点,那段代码是怎么写的呢?我想知道处理这种功能的算法是怎样的?
谁能告诉我如何在实际机器上找到处理用户输入最低级别的完整功能代码?我对了解函数以及找到获取此类代码的方法都很感兴趣。
【问题讨论】:
-
您删除了“linux-kernel”标签?你知道这个用户空间代码依赖于像 Linux 这样的操作系统,对吧?它只是调用内核。您的问题是“该代码是如何编写的”,在这种情况下 该代码 是 Linux 内核。这里没有任何与“运行”的操作系统分开的 x86 机器代码,操作系统直接通过 CPU 从 x86 加载/存储指令(编译器从 C 生成)生成的 PCI 消息与真正的硬件对话。
-
我想你希望你的问题能得到一个简短的回答,只需要内核方面的一些指令。情况远非如此,除非您想使用 BIOS 或 UEFI 服务。但这与在操作系统下使用系统调用没有什么不同,就哪种 CPU 指令实际驱动硬件而言。
-
顺便说一句,我删除了interrupt 标签,因为它只是调用 32 位 Linux 系统调用的机制。
int xx不参与实际访问键盘硬件,并且 CPU 没有任何内置的中断处理程序来执行此操作。 (BIOS 可能设置了一些,但您询问了本机/低级,例如操作系统如何在内部进行操作,这不 涉及通过旧版 BIOS 接口进行操作。)如果您运行 这段代码没有操作系统,它只会崩溃。 -
@PeterCordes,非常感谢您的全面回答。我其实对操作系统之外的底层代码很感兴趣。
-
没有看到你的回复,因为你没有@notify我。在非 x86 嵌入式系统上,除了引导加载程序之外,您通常没有为您实现任何东西的固件。所以是的,您需要的 USB 驱动程序与我在答案中链接的完全一样。您可能会简化为控制台屏幕/键盘的 API,而不是使用可重定向的文件描述符,但您仍然需要至少一个基本的 USB-HID 驱动程序才能与 USB 键盘通信。它的代码可能“看起来像”Linux 的
usbhid/usbkbd.c,但可能不太便携/模块化,并且不关心那么多特殊情况。
标签: assembly x86 keyboard low-level