386 和 amd64 之间的可移植源代码?
目标:有一个汇编源文件可以同时汇编到 x86 (i386) 和 x86_64 (amd64)?
这可能吗,例如使用 YASM 吗?
Goal: have a single assembler source file which will assemble both to x86 (i386) and to x86_64 (amd64)?
Is this possible, for instance with YASM?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
根据定义,汇编语言不能在不同的 CPU 架构之间移植。
根据您使用的汇编器,您可以做一些事情来简化移植部分,正如 Alex 所说,例如使用宏和条件汇编处理不同的寄存器或指令名称(不要认为这会使您的代码更具可读性,也不比拥有两个不同的文件更易于维护)。
但在不同的架构上,你不能指望相同的代码能够正常运行。尤其是 32 位和 64 位架构。
即使您成功地拥有了通用代码,它也肯定会缺乏不同架构中可用的优化。
最后但并非最不重要的一点是,您还会遇到 ABI 问题。即使在 x86(通常是 CDECL - 所有参数在堆栈上传递)和 x86_64(系统 V - 首先在寄存器上传递参数,然后在堆栈上传递)之间,调用约定也是不同的。
Assembly language is by definition not portable between different CPU architectures.
Depending on the assembler you use, you can do a few things that will ease the porting part, as Alex said, like dealing with different register or instruction names with macros and conditional assembly (don't think this will make your code more readable, nor more maintainable than having two distinct files).
But on different architectures, you can't expect the same code to run fine. Especially with 32 and 64 bits architectures.
Even if you succeed in having a common code, it will certainly lack optimizations available in the different architectures.
And last, but not least, you will also have ABI issues. Calling conventions are different, even between x86 (usually CDECL - all arguments passed on the stack), and x86_64 (System V - first arguments passed on registers, then on stack).
如果您使用条件汇编,则可以。但不要指望为 x86 编写一次所有代码并使其在 x64 上同样工作,或者反之亦然。使用
%if 和 %ifdef
。您还可以创建一些可以扩展到不同事物的宏。例如,某些
RAXPTR
会扩展为EAX
或RAX
,具体取决于您正在编译的平台,并且您可以使用此RAXPTR< /code> 其中 EAX/RAX 用作指针。同样,您可以创建一些宏
PARAM1/2/etc
来扩展到例程参数,例如ECX/RCX
和EDX/RDX
对于fastcall
约定中的前两个参数,[EBP+someconstant]/[RBP+someconstant]
用于其余参数。以这种方式使用宏可以帮助您编写主要可移植的 x86/x64 汇编代码,但是如果没有 %if 和 %ifdef 之类的东西,您仍然无法做到这一点。If you use conditional assemblying, you can. But don't expect to write all the code once for x86 and have it work the same on x64 or the other way around. Use
%if and %ifdef
.You could also create some macros that would expand to different things. For example, some
RAXPTR
would expand toEAX
orRAX
depending on what platform you're compiling and you can use thisRAXPTR
where EAX/RAX is used as a pointer. Likewise you could create some macrosPARAM1/2/etc
that would expand to the routine params, to things likeECX/RCX
andEDX/RDX
for the first two parameters in thefastcall
convention and[EBP+some constant]/[RBP+some constant]
for the rest. Using macros in this manner can help you write mostly portable x86/x64 assembly code, but still, you can't do this without things like %if and %ifdef.