Можно ли использовать #ifdef как проверки в ассемблере? - PullRequest
4 голосов
/ 15 июня 2011

Я немного протестировал ассемблер на Linux с использованием синтаксиса AT & T. Меня поразило то, что книга, которую я читал, была написана с 32-битной точки зрения. Таким образом, все размеры должны быть изменены на правильные 64-битные версии для меня. Или я мог бы (что я и сделал) собрать код, используя флаг - 32 для как и флаг -melf_i386 для ld при связывании. Я также адаптировал часть кода для работы в Windows под Cygwin.

Но это заставило меня задуматься. Есть ли способ сделать ifdef как проверки в ассемблере, чтобы сделать одну вещь, если я на Windows и другую под Linux , а также обработать 32 против 64 немного таким образом? Например, для .globl _start под Linux и .globl _main под Windows.

Или это выполняется путем проверки перед сборкой и создания различных исходных файлов для сборки на основе результатов проверок?

т.е. foo_linux.s и foo_windows.s

Если так, как вы преодолеете тот факт, что вы не будете знать, какие .s файлы вы будете использовать, и, следовательно, должны включать их при создании программы?

Например, скажем, что у нас есть socket_linux.s и socket_windows.s . Они оба представляют идентичный интерфейс, но выполняют специфическую для ОС работу, связанную с сокетами. Но когда я работаю с сокетами в моей программе, я не буду знать, нужна ли мне версия для Windows или Linux. Так что я бы как бы облажался :) 1043 *

Так как это обрабатывается в Ассемблере? Например, в C ++ я мог бы включить мои socket.h и socket.cpp и обернуть весь специфичный для Linux и Windows код в # ifdef .

Ответы [ 3 ]

7 голосов
/ 15 июня 2011

Если вы используете GCC для компиляции ваших файлов и присваиваете им имена .S (с заглавными буквами S) или .sx, он пропустит их через препроцессор перед вызовом ассемблера.

С Документы :

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

Вы можете добавить -v в командную строку, чтобы увидеть, как вызываются различные подпроцессы.

2 голосов
/ 10 мая 2013

в MASM (.asm), вы можете использовать ifdef, ifndef и т.п., например:

ifdef X64
endif
1 голос
/ 15 июля 2017

При написании для разных платформ вы можете определить некоторый макрос для загрузки целевых файлов:

FILE 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
...