问题标签 [real-mode]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c - JMP 不工作
好的,所以我一直在尝试在程序集/C 中制作两步引导加载程序,但我无法让 JMP 工作。起初我认为读取失败,但是,经过以下测试,我排除了这一点:
这按预期打印了“f”(扇区的第一个字节是 0x66,这是“f”的 ASCII 代码),证明读取成功并且jmp
是问题所在。这是我的代码:
运行时,我的程序只是挂起,这意味着程序可能跳转到内存中的错误位置。顺便说一句,我显然是在 VMWare 播放器下以实模式运行的。我正在使用以下命令编译它:
这是test.ld
:
注意:我已经确认这不是内联 asm 的问题——我也尝试过纯汇编实现,结果相同——我使用 C 的唯一原因是因为我打算扩展它一点,我更舒服使用 C 循环和函数...
编辑:我在这里上传了我的软盘驱动器的前三个扇区
编辑2:我无法使用任何建议让我的引导加载程序工作,并且根据@RossRidge 的建议,我编写了同一程序的汇编版本和一个简单的汇编程序来回显输入。可悲的是,这些也不起作用..
引导加载程序:
第 3 区计划:
它们都用: 编译,nasm Linux/boot.S -o Linux/asm.bin
并且行为与它们的 C 对应物相同..
x86 - 与设备驱动程序开发有关的实模式限制
我的查询是关于设备驱动程序开发的。
如果我想使用实模式制作玩具操作系统,但决定编写网络堆栈/网络驱动程序集,是否有足够的空间这样做?我是否需要像 DOS 一样切换到保护模式来完成这样的事情?
bios - 如何使用来自 GRUB 的实模式 BIOS / VESA 调用?
我正在开发一个简单的 Grub 模块,它可以在启动过程的早期阶段启用一些额外的视频设置/初始化。我实际最好的想法是使用一些 VESA 调用来完成任务。
不幸的是,最近我发现 Grub 无法进行实模式调用。
但是 GRUB 可以执行非常复杂的操作,如果没有 BIOS 的帮助,这可能是无法想象的。
这怎么可能?我怎么能从 grub 调用 bios?
x86 - 是否可以在实模式下启用分页?
是否可以在实模式下启用分页,例如在 BIOS 执行期间。如果启用它,在实模式下进行分页有什么用
assembly - Int 13h 不适用于 QEMU。程序崩溃
我正在逐步介绍如何从 stratch 构建操作系统。如果有人问,我可以发布 pdf。所以,我有这个“disk_load”调用,它没有明显的原因不起作用。我已经多次检查了每个参数,但它不起作用。
这是代码
test.asm
disk_load.asm
我收到错误消息
Disk read error: 0x000C
,我知道这意味着Media type not found (floppy)
因为print_string
并且print_hex
做得很好,我不会发布它们。
我已经浏览了每一段代码,对我来说一切都很好。
x86 - 大实模式下的地址翻译
正如http://wiki.osdev.org/Unreal_Mode所说,我有一些关于地址转换如何在大实模式下发生的问题
虚幻模式包括打破实模式段的“64Kb”限制,但仍通过调整描述符缓存来保持 16 位指令和段*16+偏移地址的形成
但我的问题是如何在过程中使用 gdt,甚至在转换为线性地址时是否使用它。如果有人可以指出切换到大实模式的某些规范或其他参考,那将非常有帮助,如果有人可以提供有关如何切换回实模式的一些见解,那将非常好。
问候,
阿尔卡
c - 一些 clang 生成的程序集不能在实模式下工作(.COM,微型内存模型)
首先,这是实模式 DOS .COM(独立式)自定义内存分配器的一种后续——如何调试?. 但是为了让它自成一体,这里是背景:
clang
(而且gcc
,也)有一个-m16
开关,所以指令集中的长指令i386
前缀用于在“16位”实模式下执行。这可以被利用来.COM
使用 GNU 链接器创建 DOS 32 位实模式可执行文件,如本博文中所述。(当然仍然限于微型内存模型,意味着所有内容都在一个 64KB 段中)想要玩这个,我创建了一个看起来工作得很好的最小运行时。
然后我尝试使用这个运行时构建我最近创建的基于 curses 的游戏,结果它崩溃了。我遇到的第一件事是经典的heisenbug:打印有问题的错误值使其正确。我找到了一个解决方法,只是为了面对下一次崩溃。所以我想到的第一件事是我的自定义malloc()
实现,请参阅另一个问题。但由于到目前为止没有人发现它有什么问题,我决定再看看我的heisenbug。它体现在以下代码片段中(请注意,在为其他平台编译时这完美无缺):
sizeof(Slot)
是 8(clang
和i386
架构),sizeof(Board)
是 20 并且w
是h
游戏板的尺寸,在 DOS 80 和 24 中运行的情况下(因为为标题/状态栏保留了一行)。为了调试这里发生的事情,我将malloc()
输出作为参数,并使用值 12 ( sizeof(board) + (-1) * sizeof(Slot)
?)
打印出来w
并h
显示正确的值,仍然malloc()
得到 12。打印输出size
显示正确计算的大小,这一次,malloc()
也得到了正确的值。所以,经典的 heisenbug。
我发现的解决方法如下所示:
很奇怪,这行得通。下一个合乎逻辑的步骤:比较生成的程序集。在这里我不得不承认我完全是新手x86
,我唯一的组装经验是和老好人在一起6502
。因此,在以下片段中,我将添加我的假设和想法作为评论,请在此处纠正我。
首先是“损坏”的原始版本(w
,h
在%esi
, %edi
):
现在,对我来说,这看起来不错,但malloc()
如前所述,我看到 12。循环的解决方法编译为以下程序集:
如前所述,第二个变体按预期工作。我的问题毕竟这么长的文字很简单......为什么?我在这里想念的实模式有什么特别之处吗?
供参考:此提交包含两个代码版本。只需键入make -f libdos.mk
具有解决方法的版本(稍后崩溃)。要编译导致错误的代码,请先从-DDOSREAL
内部删除。CFLAGS
libdos.mk
更新:鉴于评论,我尝试更深入地调试这个自己。使用 dosbox 的调试器有点麻烦,但我终于在这个 bug 的位置上破解了它。因此,以下汇编代码旨在:clang
最终是这样的(注意 dosbox 的反汇编程序使用的 intel 语法):
我认为这lea
条指令看起来很可疑,事实上,在它之后,错误的值在ax
. 因此,我尝试将相同的汇编源提供给 GNU 汇编器,并使用.code16
以下结果(反汇编objdump
,我认为它并不完全正确,因为它可能会误解大小前缀字节):
唯一的区别是这lea
条指令。这里67
以 16 位实模式下的“地址为 32 位”的含义开头。我的猜测是,这实际上是需要的,因为lea
它旨在对地址进行操作,并且只是被优化器“滥用”在这里进行数据计算。我的假设正确吗?如果是这样,这可能是clang
s 内部汇编程序中的错误-m16
吗?也许有人可以解释这个668D060C00
发出的clang
来自哪里,可能是什么意思?66
意思是“数据是 32 位的”,8D
可能是操作码本身 --- 但其余的呢?
assembly - 在实模式下跳转到远地址
我有一种情况,我必须在实模式下跳转到远地址,我在寄存器中有段值,在fs
寄存器中有偏移量gs
,在跳转期间我必须保持准确的寄存器内容,我想出了一个想法下列的,
假设bp
,fs
并且gs
没有在被调用的目标中读取,这是我刚刚在实模式下的 NASM 远跳转/远调用和 ASM 代码约定中找到的另一种方式,我可以使用,
我想知道我应该使用哪种方法,或者是否有其他方法可以实现这一点?我在x86组装方面没有太多技能,所以请原谅我的无知。
问候,
阿尔卡
networking - 如何在 NASM(自定义操作系统)中列出网络设备
我有一个完全内置在 NASM 中的自定义、类似 DOS 的操作系统(没有 C 代码)。它非常简陋(它确实有一个 FAT 文件系统、很少的应用程序、处于实模式等)。我想编写一个命令来列出当前连接的所有网络设备(网卡)。
我的假设是这样的:我需要为网卡编写一个驱动程序(为简单起见,我将它手动放在内核中,因此不存在动态加载),但该驱动程序只提供名称就足够了卡,网卡实际上不需要工作。我如何告诉操作系统将该功能精确地连接到那个网卡?这就是我所担心的,我不知道操作系统通常如何将硬件与代码(其驱动程序)匹配。
assembly - 为什么我们在 16 位实模式下只能访问 1MB?
我不明白为什么我们在 16 位实模式下只能访问 1MB 的内存。1MB 限制是否表示内存访问?我知道当系统启动时,由于向后兼容,我们被限制为 16 位寄存器,但为什么要限制内存以及如何限制?