Search code examples
assemblygnu-assembler

Is there a __LINE__ macro for GAS assembly that expands to the current source line number?


Like in NASM and C.

Simply preprocessing it with cpp does not work since I want to define a macro like:

.macro ASSERT_FAIL
    mov __LINE__, %eax
    call assert_fail
.endmacro

which expands the __LINE__ whenever ASSERT_FAIL is used so I can see where the failure happened. So __LINE__ must be expanded after ASSERT_FAIL.

I would also like to put that macro in a separate file and include it with .include.

I have been able to achieve exactly that with NASM:

%macro ASSERT_FAIL 0
    mov eax, __LINE__
    call assert_fail
%endmacro

Is there any alternative besides using cpp's #include and #define instead of .macro and .include? The manual does say that there are little built-in pre-processing power in gas. It makes me wonder why .macro and .include exist at all if they are so limited.

EDIT: I have examined the kernel and glibc. glibc does not have a single .include and very few .macro. The kernel has no .include, but uses a mixture of both .macro and #define, with a tendency of leaving .macro for multi-line macros as it is more readable.


Solution

  • As mentioned by @RossRidge, the best solution I could find so far was to use cpp and use:

    #define ASSERT_FAIL \
        mov $__LINE__, %eax ;\
        call assert_fail
    

    This also requires any macro that use this to use CPP and not .macro, and #include and not .include. So the best thing to do is to use only cpp for macros everywhere.

    If you use the standard .S (uppercase) extension, gcc 4.8 automatically runs cpp by default, which is convenient.

    But if your use case is a bit different, make sure to explore other GCC features. For example, I was also considering using __LINE__ to generate unique local labels, but then I found the numeric local relative labels which were a much better option.