【问题标题】:How to program in 16 bit protected mode with more than 64kb of data?如何使用超过 64kb 的数据在 16 位保护模式下编程?
【发布时间】:2015-05-06 15:44:47
【问题描述】:

我想为 16 位保护模式编写一些代码,特别是一个带有一些程序的简单操作系统。我知道这听起来很傻,而且可能确实如此,但我有兴趣了解如何在这些限制下编写程序。

我想知道在 16 位保护模式下工作的各种操作系统(例如 OS/2 和 Win 3.1)中采用了哪些类型的约定。他们使用了什么 ABI? far 指针是如何传递的?是否有针对不同代码模型的多个 ABI?

为了澄清,我知道什么是远指针以及它们在 API 级别上的使用方式。我想知道的是这在装配级别上是如何工作的。远指针的段是否在堆栈上传递?有什么特殊约定吗?

【问题讨论】:

    标签: assembly abi protected-mode 80286


    【解决方案1】:

    大多数 16 位保护模式 API 将远指针作为参数。远指针是一个 32 位值,包含 16 位偏移量(低位字)和 16 位选择器(高位字,选择器指段)。它像任何其他参数一样通过将其放在堆栈上来按值传递。通常,这些指针只能引用最大 65536 字节的内存区域,但不同的远指针可以引用不同的内存区域,允许使用超过 64K 的内存。

    例如,在 16 位 Windows API (Win16) 中,函数 GetClientRect 具有以下文档化接口:

    void GetClientRect(hwnd, lprc)
    
    HWND hwnd;    /* handle of window */
    RECT FAR* lprc;   /* address of structure for rectangle   */
    

    符号 FAR 是一个宏,在使用 16 位 Windows API 时扩展为 far 关键字。今天,此 API 函数被记录为采用 LPRECT 参数,该参数被解读为“指向 RECT 的长(远)指针”。符号 LPRECT 在 32 位和 64 位 Windows API 中定义为 RECT * 的 typedef。如果仍然支持 16 位 API,则它的 typedef 为 RECT far *

    没有针对不同内存模型(小型、中型、紧凑型、大型)的单独 API,因为在指针(以及函数本身)上使用了 far 关键字,所有内存模型都可以访问 API。编译器会看到它使用了一个远指针并根据需要提升任何近(16 位)指针。

    【讨论】:

    • 这些指针是如何传递的?是否有任何 ABI 文档可以链接到我?我知道人们使用远指针(请参阅我的问题),但我想看一些具体的例子,以便更好地理解。
    • 远指针由 32 位指针的低位字中的 16 位偏移量和作为高位字的 16 位选择器组成。我不知道是否有人写过任何实际的 ABI 文档,我认为 16 位调用约定早于 ABI 一词,但我给出了一个 16 位 API 示例,取自我的旧 Borland C++ 3.1 文档。
    • 我实际上想知道这在机器代码级别上是如何工作的。因为如果我想为自己的系统编写这样的代码,那就是我需要知道的。我知道什么是远指针以及它们如何在 ABI 级别上使用。您的回答并没有回答我的大部分问题(例如,这是如何在 ABI 级别实现的)并且并没有真正增加我已经知道的内容。不过感谢您的努力。
    • @FUZxxl 我只能回答您实际提出的问题。正如我所说,远指针是 32 位值。它们像任何其他 32 位值一样在堆栈上传递。如果这是你的问题,你应该问那个。
    • 那么在段寄存器等中传递段没有任何特殊约定?
    【解决方案2】:

    据我记得从前引入了具有 80286 架构的 AT 系统,内存由 64 KB 段组成,这是可以使用 16 位地址寄存器(实模式)寻址的最大地址。当在汇编中进行编码时,近跳和远跳可能分别发生在段内或段外。当发生远跳转时,在汇编中,您应该首先给出将发生跳转的段,然后给出段内的本地地址。

    在保护模式下,描述符表可用于扩展段的寻址范围,从而增加机器上可使用的内存量。

    如果代码实现为可重入,则可以使用适当的 BIOS 和操作系统中断来实现多任务以及终止和驻留 (TSR) 程序。

    【讨论】:

    • 抱歉,您的回答没有回答我的任何问题。你能给我一些关于使用的 ABI 以及指针传递多远的例子吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-26
    • 2021-04-22
    • 1970-01-01
    相关资源
    最近更新 更多