我对平台依赖感到困惑。我想直截了当。因此,如果我理解正确,特定的硬件架构将具有特定的指令集。
右?例如。如果我们谈论英特尔8086处理器,那么这个处理器就有一个特定的指令集。如果我在这个指令集中编码,则意味着我使用Intel 8086支持的汇编语言进行编码。对吗?
现在,这种特殊的处理器架构可以被各种机器和操作系统使用。例如。使用Mountain Lion OSX的一台MAC,一台使用Ubuntu作为其操作系统的Lenovo机器和一台使用Windows 7作为其操作系统的Sony VAIO机器,所有这些机器都可以将其底层处理器架构作为Intel 8086。对吧?
所以现在如果我用英特尔8086处理器的汇编语言编写代码(比如添加2个数字),这个代码应该在上面提到的所有3台机器上运行没有任何问题。一个普通的汇编程序应该能够将这些代码转换为所有这三台机器上的机器级代码。正确?
现在,平台依赖在这里出现了什么?由于asm代码是针对相同的底层处理器架构编写的,它是否应该只在所有平台上运行?
我只想弄清楚我哪里出错并且感到困惑。我在这里错过了什么?如果问题听起来令人困惑或愚蠢,请耐心等待。
答案 0 :(得分:8)
我会给你一个糟糕的汽车类比,说明为什么会有问题。
所有品牌的汽车均采用相同类型的螺钉和螺栓(8086代码)构建
虽然您可以从福特(Windows)中取出螺丝并将其拧入丰田(OSX),但您不能从福特(Internet Explorer)上取下车身面板并将其固定在丰田(OSX)上
面板可以使用相同类型的螺钉和螺栓固定,但面板永远不会适合两个品牌。
因此,虽然您可以在Windows和OSX之间使用相同的基本指令来构建基本内容,但是一旦您开始以OS的风格构建内容,就无法再交换它们。这将引领你走平台依赖的道路。
(我告诉过你这将是一个不好的比喻)
答案 1 :(得分:6)
不幸的是,如果不使用API和ABI进行输入和输出,那么汇编语言程序就不会走得太远。并且API和ABI 依赖于平台。
答案 2 :(得分:1)
首先,“8086”不再严格准确。自第一次发布以来,指令集已有数字扩展,特别是当它扩展到64位时。因此,一个不兼容的来源是代码是打算在64位还是32位模式(甚至是16位模式)下运行。
无论如何问题是硬件和操作系统之间的接口。 x86指令集的汇编代码对于所有三个都是相同的,但生成的机器代码可能/仍然不兼容。不同的操作系统可能会对系统调用表,函数入口和出口以及堆栈分配等事物使用不同的常量,约定或原理图。例如,在64位中,大多数x86 Unices使用寄存器用于前6个参数,然后将其余部分推送到堆栈,而Windows仅使用寄存器用于前4个,并将另外的32字节字段推送到堆栈以镜像那些在每个函数调用上注册。使用哪些寄存器也有所不同,例如: Windows将第一个非浮点参数放在RCX中,但Unix使用RDI。 您 可以使用编译器宏来解释所有这些,但是你没有二进制兼容性。
答案 3 :(得分:1)
x86在很多方面都是一个特别痛苦的指令集。特别是你甚至不能说在汇编语言中简单地添加两个数字是可以在许多x86计算机上移植的,因为有太多不同的汇编程序具有至少两种主要的语法风格。
所以不,你不能说如果你用一行asm添加它会移植的两个数字。
你可能会说其他一些指令集,但这只是学术性的,因为正如Peter M所说,螺栓和金属板可能都来自同一个地方,但门不可互换。
我可以采用相同的砖块和相同的砂浆,并建造不同的,不相容的建筑物,用于不同的目的。因此,砌砖技术是可移植的,但我们用它们构建的不是。
许多其他编程语言也是如此,其中一些最初设计为可移植的。