X86 386和amd64之间的可移植源代码?

X86 386和amd64之间的可移植源代码?,x86,assembly,i386,x86-64,X86,Assembly,I386,X86 64,目标:有一个汇编程序源文件,可以同时汇编到x86(i386)和x86_64(amd64) 这是否可能,例如,使用?如果使用条件组装,则可以。但不要期望为x86编写一次所有代码,并让它在x64上以同样的方式工作,或者以其他方式工作。使用 您还可以创建一些宏,这些宏可以扩展到不同的对象。例如,一些RAXPTR将扩展到EAX或RAX,具体取决于您正在编译的平台,并且您可以在EAX/RAX用作指针的位置使用此RAXPTR。同样,您可以创建一些宏PARAM1/2/etc,这些宏将扩展到例程参数,为fast

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


这是否可能,例如,使用?

如果使用条件组装,则可以。但不要期望为x86编写一次所有代码,并让它在x64上以同样的方式工作,或者以其他方式工作。使用


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

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


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

根据定义,汇编语言在不同的CPU体系结构之间是不可移植的

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

但是在不同的体系结构上,您不能期望相同的代码能够正常运行。特别是32位和64位体系结构

即使您成功地获得了一个通用代码,它也肯定会缺少在不同体系结构中可用的优化


最后,但并非最不重要的是,您还将有ABI问题。调用约定是不同的,甚至在x86(通常是CDECL-所有在堆栈上传递的参数)和x86_64(System V-首先在寄存器上传递参数,然后在堆栈上传递参数)之间也是不同的。

根据定义,汇编语言在不同的CPU体系结构之间是不可移植的

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

但是在不同的体系结构上,您不能期望相同的代码能够正常运行。特别是32位和64位体系结构

即使您成功地获得了一个通用代码,它也肯定会缺少在不同体系结构中可用的优化


最后,但并非最不重要的是,您还将有ABI问题。调用约定是不同的,甚至在x86(通常是CDECL-所有在堆栈上传递的参数)和x86_64(System V-首先在寄存器上传递参数,然后在堆栈上传递参数)之间也是如此。

@AmigableClarkKant:它主要是一个超集。但这主要是因为一些在非64位模式下可用的东西在64位模式下不再可用。但最重要的是,你们用来保存各种变量地址的寄存器,它们必须在32位和64位上有所不同:E-something和R-something。而且不同的呼叫约定/ABI也在阻碍。使用宏可以在这里提供帮助,请参阅更新的答案。嗯,没有%if和%ifdef我就不能做是什么意思?你的意思是说那些必须在RAXPTR宏中吗?@AmigableClarkKant:是的。或者在外面,如果你更喜欢的话。这与C/C++的#if/#ifdef是一样的。这就是为什么有人发明了C语言@AmigableClarkKant:它主要是一个超集。但这主要是因为一些在非64位模式下可用的东西在64位模式下不再可用。但最重要的是,你们用来保存各种变量地址的寄存器,它们必须在32位和64位上有所不同:E-something和R-something。而且不同的呼叫约定/ABI也在阻碍。使用宏可以在这里提供帮助,请参阅更新的答案。嗯,没有%if和%ifdef我就不能做是什么意思?你的意思是说那些必须在RAXPTR宏中吗?@AmigableClarkKant:是的。或者在外面,如果你更喜欢的话。这与C/C++的#if/#ifdef是一样的。这就是为什么有人发明了C语言!这说明了前面的困难,并且+1表示这一点。但考虑到我有用于调用约定(不知道这有多可行)和寄存器的宏,你认为这可能吗?@AmigableClarkKant:这很可能。但是,在编写这种“可移植”代码时,您必须经常考虑两种模式/平台及其差异,并将它们隐藏在宏后面。这就是为什么它不像为x86编写一段代码,然后像在x64上那样重用它,或者以其他方式重用它。但考虑到我有用于调用约定(不知道这有多可行)和寄存器的宏,你认为这是可行的吗