Assembly 如何在编译时检测NASM中的体系结构,使x64和x86都有一个源代码?
我正在寻找nasm中的一些预处理器功能,这些功能允许为x86和x64体系结构提供一个源代码 我的意思是,如果定义了某个常量。就像C预处理器一样,如果它想检测,比如说它是在Windows或Linux上编译的 编辑Assembly 如何在编译时检测NASM中的体系结构,使x64和x86都有一个源代码?,assembly,x86,preprocessor,nasm,x86-64,Assembly,X86,Preprocessor,Nasm,X86 64,我正在寻找nasm中的一些预处理器功能,这些功能允许为x86和x64体系结构提供一个源代码 我的意思是,如果定义了某个常量。就像C预处理器一样,如果它想检测,比如说它是在Windows或Linux上编译的 编辑 我知道nasm旗。我使用它们。我只想拥有完全相同的源代码,并期望预处理器根据这些标志正确处理它。我会用ifdef。。。else用于堆栈操作等,两种体系结构的核心代码相同。NASM无法检测体系结构,但您可以根据需要使用输出格式(命令行选项:-felf、-felf32、-felf64、-fw
我知道nasm旗。我使用它们。我只想拥有完全相同的源代码,并期望预处理器根据这些标志正确处理它。我会用ifdef。。。else用于堆栈操作等,两种体系结构的核心代码相同。NASM无法检测体系结构,但您可以根据需要使用输出格式(命令行选项:-felf、-felf32、-felf64、-fwin32等)。阅读NASMX软件包中的.,您可以在syscalls.inc中找到%if位==64行。这将确定您使用的是nasm 64位还是32位。也许这就是你想知道的?
\uuu输出格式\uuuu
\uuuu输出格式\uuuu
标准宏保存当前输出格式,如-f
选项或NASM的默认值所示。键入nasm-hf
以查看列表
%ifidn __OUTPUT_FORMAT__, win32
%define NEWLINE 13, 10
%elifidn __OUTPUT_FORMAT__, elf32
%define NEWLINE 10
%endif
NASM允许您随意更改代码大小(使用
bits
指令),允许您在elf64中使用16位或32位代码,或在elf32中使用64位代码。因此,检测输出格式相对错误(脆弱)
相反,您希望检测当前代码大小。为此,NASM有一个名为\uuu BITS\uu
的标准宏。这意味着您可以在位=64时执行%
然而,32位代码和64位代码通常使用完全不同的调用约定;64位代码有更多的寄存器、更宽的寄存器和其他差异(如果不使用额外的寄存器或额外的宽度,则意味着代码的质量极低,远远低于编译器生成的代码)。这意味着(不包括仅对几个小宏使用它)试图在同一代码中同时支持32位和64位是非常愚蠢的。您只需要为完全不同的情况编写完全不同的代码,这些代码被毫无理由地插入到同一个文件中,然后分离(使用预处理器魔术)以解决一个事实,即它从一开始就没有意义
更明智的做法是为不同的情况使用不同的文件(例如,一个src/arch/x86_32
目录和一个src/arch/x86_64
目录),在这种情况下,您可以让构建脚本或makefile对其进行排序(例如,告诉汇编程序使用不同的“包含路径”)。对于这一点,架构是两种不同的。您将无法利用额外的寄存器,等等。坚持32位代码,或者考虑一个编译的但足够低级的语言,如C.It,由可执行格式中的标志决定,因此,您不能同时拥有这两种体系结构,因为预处理器无法通过让程序员使用ifdef x64 do_sth1 else do_sth2?@infoholic_anonymous这样的宏来利用这些标志:您可以在x64系统上构建和运行32位程序。那么架构检测有什么意义呢?但是您可以检索构建选项(\uuuuuu输出\uuuu格式
)。你看过说明书了吗?如果通过脚本构建程序,则可以使用uname-m
检索机器。我做了一个非常简单的项目,必须为x64和x86提供代码。在我的代码中,差异很小,主要涉及到调用约定的问题和寄存器名之类的问题。寄存器名可以由定义和调用约定替换为几行ifdef。为什么我要保留两个文件,并在更改时对其进行双重更正?我很惊讶这看起来很奇怪,在命令行程序的C源代码中,有些代码段依赖于操作系统是很常见的。我尝试了输出_格式来区分elf32和elf64,但没有结果。@Agguro感谢您的报告。您能否在NASM问题跟踪程序/邮件列表上打开一个问题并从这里链接到它?