( OnlyZaenae | 2025. 08. 23., szo – 13:20 )

Itt jön a válasz...

? 2025-08-23 16:04

Two portable-ish GNU C ways:

1) asm goto (best if your GCC supports it)

asm goto lets inline assembly branch to C labels directly.

#include <stdio.h>

void demo(int x) {
    asm goto(
        "test %0, %0\n\t"
        "jz %l[is_zero]\n\t"
        :
        : "r"(x)          // inputs
        :                  // clobbers (add "memory" if needed)
        : is_zero          // C label(s) you may jump to
    );
    puts("non-zero");
    return;

is_zero:
    puts("zero");
}

Notes:

  • Use %l[labelname] (or %l0 etc.) in the asm template to reference a C label from the final : ... : labels list.

  • Add "memory" to clobbers if the asm influences memory-observable state.

  • Supported by GCC 4.5+; Clang supports it only in newer versions (and not on all targets).

2) “Labels as values” + indirect jump (fallback)

If you can’t use asm goto, take the address of a C label (GNU C extension) and jump to it indirectly:

#include <stdio.h>

void demo(int x) {
    void *target = &&nonzero;
    if (x == 0) target = &&zero;

    // Jump via register operand
    __asm__ volatile ("jmp *%0" :: "r"(target));

zero:
    puts("zero");
    return;

nonzero:
    puts("non-zero");
}

Notes:

  • This uses GNU C’s computed goto (&&label) plus an indirect jmp *reg.

  • Works in C (GNU C); not standard C/C++.

  • The inline asm sees the label address as a normal pointer operand.

Which should I use?

  • Prefer asm goto when available: it’s designed for exactly this use case and integrates with the optimizer/control flow.

  • Use the computed-goto + indirect jmp trick if asm goto isn’t available on your compiler/target.

If you share your exact target (arch/OS) and GCC/Clang versions, I can tailor the snippet (e.g., different jump mnemonics, clobbers, or constraints).