【问题标题】:Portable source code between 386 and amd64?386和amd64之间的可移植源代码?
【发布时间】:2011-11-23 23:19:01
【问题描述】:

目标:拥有一个汇编源文件,可以同时汇编到 x86 (i386) 和 x86_64 (amd64)?

这可能吗,例如YASM?

【问题讨论】:

    标签: x86 assembly i386 x86-64


    【解决方案1】:

    根据定义,汇编语言不能在不同的 CPU 架构之间移植。

    根据您使用的汇编器,您可以做一些可以简化移植部分的事情,正如 Alex 所说,例如使用宏和条件汇编处理不同的寄存器或指令名称(不要认为这会使您的代码比拥有两个不同的文件更具可读性,也更易于维护)。

    但在不同的架构上,您不能指望相同的代码运行良好。尤其是 32 位和 64 位架构。

    即使你成功地拥有了一个通用代码,它也肯定缺乏不同架构中可用的优化。

    最后但并非最不重要的一点是,您还会遇到 ABI 问题。调用约定是不同的,即使在 x86(通常是 CDECL - 所有参数都在堆栈上传递)和 x86_64(System V - 第一个参数在寄存器上传递,然后在堆栈上)之间也是如此。

    【讨论】:

    • 这说明了未来的困难,并为此 +1。但是考虑到我有调用约定的宏(不知道这有多可行)和寄存器,你认为这可能吗?
    • @AmigableClarkKant:很有可能。但是在编写这种“可移植”代码时,您必须不断考虑模式/平台及其差异,并将它们隐藏在宏后面。这就是为什么它不像为 x86 编写一段代码,然后在 x64 上按原样重用它,或者相反。
    【解决方案2】:

    如果您使用条件汇编,则可以。但是不要期望为 x86 编写一次所有代码,并让它在 x64 上或以其他方式工作。使用%if and %ifdef。

    您还可以创建一些可以扩展到不同事物的宏。例如,某些RAXPTR 会扩展为EAX 或RAX,具体取决于您正在编译的平台,您可以使用RAXPTR,其中EAX/RAX 用作指针。同样,您可以创建一些宏 PARAM1/2/etc,这些宏将扩展为常规参数,例如 ECX/RCX 和 EDX/RDX 用于 fastcall 约定中的前两个参数,[EBP+some constant]/[RBP+some constant] 用于其余参数。以这种方式使用宏可以帮助您编写大部分可移植的 x86/x64 汇编代码,但是,如果没有 %if 和 %ifdef 之类的东西,您仍然无法做到这一点。

    【讨论】:

    • @AmigableClarkKant:它主要是一个超集。但主要是因为某些在非 64 位模式下可用的东西在 64 位模式下不再可用。但最重要的是,用于保存各种变量地址的寄存器在 32 位和 64 位中必须不同:E-something 与 R-something。并且不同的调用约定/ABI 也在阻碍。在此处使用宏可以提供帮助,请参阅更新后的答案。
    • 嗯,你的意思是我不能没有 %if 和 %ifdef?你的意思是那些必须在例如 RAXPTR 宏里面?
    • @AmigableClarkKant:是的。或者在外面,如果你更喜欢的话。与 C/C++ 的#if/#ifdef 相同。
    • 这正是有人发明了 C 语言的原因!
    猜你喜欢
    • 2013-11-30
    • 2012-11-22
    • 1970-01-01
    • 2015-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-08
    相关资源
    最近更新 更多