【问题标题】:Is it possible to use #ifdef like checks in assembler?是否可以在汇编程序中使用#ifdef 之类的检查?
【发布时间】:2011-09-15 14:26:42
【问题描述】:

我在 Linux 上使用 AT&T 语法测试了一些汇编程序。让我印象深刻的一件事是,我正在阅读的这本书是从 32 位的角度编写的。因此,对于我来说,所有大小都必须更改为正确的 64 位版本。或者我可以(我这样做了)使用 as--32 标志和 ld 的 -melf_i386 标志来组装代码 链接时。我还修改了一些代码,并在 Cygwin 下运行在 Windows 上。

但这让我开始思考。如果我在 WindowsLinux 下的另一件事,并且还处理 32 对 64 位那样?例如,在 Linux 下有一个 .globl _start,在 Windows 下有一个 .globl _main

或者这是通过在组装前检查并根据检查结果组装不同的源文件来处理的?

foo_linux.sfoo_windows.s

如果是这样,您如何克服在创建程序时不知道将使用哪些 .s 文件并因此必须包括在内的事实?

例如,假设我们有一个 socket_linux.s 和一个 socket_windows.s。它们都提供相同的接口,但执行与套接字相关的操作系统特定工作。但是当我在我的程序中使用套接字时,我不知道我是否需要包含 Windows 或 Linux 版本。所以我会有点搞砸:)

那么在 Assembler 中是如何处理的呢?例如,在 C++ 中,我可以包含我的 socket.hsocket.cpp 并将所有 Linux 和 Windows 特定代码包装在 #ifdef 语句中。

【问题讨论】:

    标签: cross-platform assembly platform-independent


    【解决方案1】:

    在为不同平台编写时,您可以定义一些宏来加载目标特定文件:

    文件target.h

    #if defined(__arm__)
        #define target "arm"
    #elif defined(__x86_64__)
        #if defined(_WIN64)
            #define target "win64"
        #else
            #define target "linux64"  // all non-Win share the same calling convention
        #endif
    #else
        // 32bit defs
    #endif
    

    然后你可以用宏包含目标特定的文件,两个字符串文字依次得到一个文字:

    #include "target.h"
    
    #include "target_specific_code_" target ".h"
    

    它包括以下文件之一:

    target_specific_code_arm.h
    target_specific_code_win64.h
    target_specific_code_linux64.h
    ...
    

    编辑:

    像这样,你也可以定义目标特定的汇编指令,供以后在内联汇编中使用:

    #ifdef ...
        #define ASM_PP_LOAD_WORD "movi "
    #else
        #define ASM_PP_LOAD_WORD "mov "
    #endif
    

    或作为宏

    #ifdef ...
        // when using intel assembler there is a different
        // order of parameters
        #define ASM_PP_LOAD_WORD(a, b) "movi " #b ", " #a
    #else
        #define ASM_PP_LOAD_WORD(a, b) "mov " #a ", " #b
    #endif
    

    【讨论】:

    • 使用字符串粘贴生成包含文件名的有趣建议。我没想到那会奏效。不幸的是,x86-64 Linux 和 Windows 确实使用不同的调用约定,因此如果您想使用标准 ABI 从 C/C++ 直接调用您的函数,则需要不同的宏。
    【解决方案2】:

    如果您使用 GCC 编译文件并将它们命名为 .S(带有大写 S)或 .sx,它将在调用汇编程序之前将它们传递给预处理器。

    来自the docs

    file.s
       Assembler code. 
    file.S
    file.sx
       Assembler code which must be preprocessed.
    

    您可以在命令行中添加-v,查看各个子流程是如何被调用的。

    【讨论】:

      【解决方案3】:

      在MASM(.asm)中,可以使用ifdefifndef等,如:

      ifdef X64
      endif
      

      【讨论】:

      • 相关:NASM/YASM 没有预定义很多宏来让您使用%ifdef / %endif 轻松检测平台。请参阅this Q&A 了解一些平台检测技巧。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-10-31
      • 2016-01-16
      • 2011-05-09
      • 1970-01-01
      • 1970-01-01
      • 2011-11-17
      • 2010-12-30
      相关资源
      最近更新 更多