什么是FAR PASCAL?

26

我想知道为什么有些源代码中会出现像FAR和PASCAL这样的宏定义。它们的意思是什么,有什么作用?


11
他们使用了一台时光机,然后一个年仅30岁的比尔·盖茨出现并要求拿回他的640k。 - R.. GitHub STOP HELPING ICE
7个回答

24
  • PASCAL: 这与调用约定有关。参数按从左到右的顺序推入堆栈 (跟 cdecl 相反),调用方在返回前负责平衡堆栈。

    这种调用约定在以下 16 位 API 中很常见:OS/2 1.x 和 Microsoft Windows 3.x。对于 Borland Delphi 1.x 是否使用了这种调用约定存在一些争议。

  • FAR: 在分段式计算机结构中,far 指针是指包含段选择器的指针,使得可以指向当前段以外的地址。

为了完整起见,FAR 和 PASCAL 是预处理器宏,在编译 16 位系统时会扩展为必要的关键字以声明调用约定和指针大小。在 32 位系统上,它们通常不会扩展为任何内容(除非您有奇怪的默认调用约定)。这些宏保留了向后兼容性 {hat/tip: Adrian McCarthy 的评论}。


我非常确定默认的Delphi调用约定一直是register。它只在Windows API和其他DLL中使用pascal函数。 - Rob Kennedy
3
为了完整性,FARPASCAL是预处理器宏,在编译16位系统时,会扩展为必要的关键字以声明调用约定和指针大小。在32位系统上,它们通常不会扩展为任何内容(除非您使用了奇怪的默认调用约定)。这些宏保留用于向后兼容。 - Adrian McCarthy

9

根据我的记忆,FAR 是回退到 16 位时代的一种方法,当时堆内存是分段的。NEAR 数据有大小限制但更快,而 FAR 可以更大但更昂贵。

据我所知,在 32 位环境中,它是一个折叠为无的宏。

PASCAL 是一种调用约定,在 16 位时代也被广泛使用。现已被 stdcall 替换。

两者都保留了向后兼容性。


7

FAR已经过时了,它在16位代码中用于表示指针可以寻址整个地址空间,而不仅仅是当前段的16位偏移量。

PASCAL是一种调用约定。正如维基百科所描述的:

参数按从左到右的顺序推入堆栈(与cdecl相反),被调用方负责在返回之前平衡堆栈。

这种调用约定在以下16位API中很常见:OS/2 1.x, Microsoft Windows 3.x和Borland Delphi版本1.x。


马克,我是C++的新手,被要求将一些旧的C/C++代码转换为C++11。数据类型short FAR*被广泛采用,但在VS2013中无法解决 - 我应该替换它们吗?如果是这样,用什么替换呢? - MoonKnight
@Killercam,你应该可以在任何地方使用FARNEAR关键字。尽管我很惊讶微软的头文件中它们没有被定义为空宏,因为他们是向后兼容的王者。 - Mark Ransom

3

FAR是16位时代的遗留物,当时我们有近(16位)和远(32位)指针。

PASCAL是一种调用约定。我相信现在它等同于stdcall


2

这是一个古老的调用约定...

FAR继承自处理器寄存器太小以容纳完整跳转目标地址的时代。因此,处理器有两种不同类型的跳转方式,取决于目标距离当前程序计数器的“远近”。

PASCAL描述了栈上参数的顺序,它表示函数使用Pascal编程语言描述的顺序,该顺序与C语言不同。(像MacOS和Windows这样的非常旧版本的操作系统是使用Pascal开发的)。


1

这可能是16位时代留下来的一些冗余/过时的代码。

FAR曾在16位应用程序中使用,以表示所需地址超过16位。

PASCAL(altion)是一种转换类型,它让编译器知道如何排列堆栈(使用PASCAL调用约定),以便编译器可以传递适当的参数到函数中并从函数中返回。

希望对你有所帮助。


1

具体来说,PASCAL规定函数的参数按从左到右的顺序传递,这样可以减小代码的大小(因为调用者知道堆栈的大小,所以可以清理它)。

C stdcall按从右到左的顺序传递参数,这意味着您可以有可变数量的参数,但需要更多的代码来清理。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接