是否可以在汇编程序中使用#ifdef之类的检查?

时间:2011-06-15 14:26:43

标签: cross-platform assembly platform-independent

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

但那让我思考。有没有办法在汇编程序中执行 ifdef 检查,如果我在 Windows 上执行一项操作,而在 Linux 下执行另一项操作并处理<那么强> 32 vs 64 那么?例如,在Linux下使用 .globl _start ,在Windows下使用 .globl _main

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

即。 foo_linux.s foo_windows.s

如果是这样,你如何克服这样一个事实:你不会知道你将使用哪些 .s 文件,因此在创建程序时必须包含这些文件?

例如,假设我们有 socket_linux.s socket_windows.s 。它们都呈现相同的接口,但执行与套接字关联的OS特定工作。但是当我在我的程序中使用套接字时,我不知道是否需要包含Windows或Linux版本。所以我会有点紧张:)

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

3 个答案:

答案 0 :(得分:7)

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

来自the docs

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

您可以将-v添加到命令行以查看如何调用各个子进程。

答案 1 :(得分:2)

在MASM(.asm)中

,您可以使用ifdefifndef等喜欢的内容:

ifdef X64
endif

答案 2 :(得分: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