0

I want to write some code for the 16 bit protected mode, specifically a simple operating system with some programs. I know this sounds silly and it probably is, but I'm interested in understanding how to write programs under these constraints.

I'd like to know what kinds of conventions have been employed in the various operating systems working in 16 bit protected mode (e.g. OS/2 and Win 3.1). What ABI did they use? How are far pointers passed around? Were there multiple ABIs for different code models?

To clarify, I know what far pointers are and how they are used on the API level. What I'd like to know is how this works on assembly level. Are segments for far pointers passed on the stack? Are there any special conventions?

4

2 回答 2

2

大多数 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   */

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

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

于 2015-05-06T16:01:01.483 回答
1

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

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

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

于 2015-05-06T16:16:42.033 回答