Der GCC beschwert sich, weil ein direkter far jump nur mit immediate Operanden funktioniert, aber nicht mit Registern.
Du hast mindestens diese drei Möglichkeiten:
1. das Laden des Segment Registers von dem Sprung zu trennen, d. h. ein far jump gefolgt von einem near jump
2. indirekter Sprung, z. B. über den Stack
3. selbstmodifizierender Code
1. solltest du nehmen, wenn der Sprung und das Neuladen des Segmentregisters nicht gleichzeitig passieren müssen
__asm__ __volatile__ (
"ljmp $0x20, $1f\n"
"1:\n"
"jmp *%0\n"
: : "r"(address)
);
2. wenn CS und EIP gleichzeitig geladen werden müssen
a) über den Stack
__asm__ __volatile__ (
"pushl $0x20\n"
"pushl %0\n"
"lret\n"
: : "r"(address)
);
b) über den Speicher
struct { unsigned int offs; unsigned int seg; } ptr = { (unsigned int)address, 0x20 };
__asm__ __volatile__ (
"ljmp *%0\n"
: : "m"(ptr)
);
3. empfehle ich nicht