我知道在程序集中编写任何内容,或者将程序集添加到任何程序都会损害其可移植性。但是,有多糟糕?我的意思是,这些天基本上所有PC都是x86或x64,对吗?那么,如果我将汇编嵌入到C程序中,为什么不管它在哪里都可以编译呢?
当你真正深入挖掘特定处理器的特定怪癖时,这种不可移植性的概念是否只是指代从一段代码中挤出每一滴性能?
如果我没记错的话,PC游戏“过山车大亨”几乎完全用汇编语言写成。那么......它真的有多么难以置信?
答案 0 :(得分:16)
除了处理器本身之外,当然还有其他一些注意事项:目标平台上的调用约定是什么? struct
值如何传递给其他(例如:API)函数?哪些寄存器可能被被调用者破坏?保证为呼叫者保留哪些内容?如何进行系统调用?操作系统在进程启动时为您准备的内存布局是什么?
答案 1 :(得分:11)
移植程序集,还存在ABI的问题,因OS而异。将一个C程序从Unix移植到Windows(甚至从Linux移植到OpenBSD)可能是一个简单的重新编译,但对于汇编程序,您可能会发现一些被调用者保存寄存器变为调用者保存,或者浮点参数是通过不同的方式。
这不仅仅是理论上的,即。注册Linux和Mac OS X的PowerPC版本的r2。实际上问题可能不会太糟糕,例如AMD在其64位指令集的同时发布了“推荐”的ABI。
答案 2 :(得分:9)
如果您认为“PC == Windows”,那么将汇编程序添加到C程序并不会造成太大损害。如果你进入Unix世界,你将拥有许多不同的CPU:PS3或XBox中的PPC,旧Mac和许多功能强大的服务器。对于许多小型设备,您将拥有ARM。嵌入式设备(占当今绝大多数已安装的CPU)通常使用自己的自定义CPU和特殊指令集。
因此,虽然今天许多PC都可以运行英特尔代码,但只占所有CPU的一小部分。
也就是说,x86代码并不总是相同。汇编代码有两个主要原因:您需要访问特殊功能(如中断寄存器)或者您希望优化代码。在第一种情况下,代码非常便携。在后一种情况下,每个CPU都有点不同。其中一些人有SSE。但SSE很快被SSE2取代,后者被SSE3和SSE4取代。 AMD拥有自己的品牌。很快,将有AVX。在操作码级别上,每个版本的CPU都有不同的时序。
更糟糕的是,某些操作码具有在CPU的特定步进中修复的错误。最重要的是,某些操作码在某些版本的CPU上比在其他版本上快得多。
接下来,您需要将此汇编代码与C部分对接。这通常意味着您需要处理ABI问题。
所以你可以看到这可能变得任意复杂。
答案 3 :(得分:3)
但即使是现在手臂处理器又回来了(即下一代网络书),我相信处理器明年是否会发生变化。
我会说汇编语言设计不可移植。