Lowlevel

Lowlevel => Softwareentwicklung => Thema gestartet von: OsDevNewbie am 30. June 2012, 18:02

Titel: Farjump zum Registerwert und mit Segmentänderung
Beitrag von: OsDevNewbie am 30. June 2012, 18:02
Hallo,
ich möchte einen Farjump zu einer Adresse vollziehen, die in einem Register drinnen steht. Zusätzlich möchte ich in ein anderes Codesegment wechhseln. Mein Code lautet:
asm("ljmp $0x20,%0" : :"r"(Adresse));
Ich habe schon gelesen, dass man vor dem Register ein Stern (*) hinmachen muss. Das habe ich auch getan, aber GCC gibt immer noch den Fehler aus, dass die Parameter für ljmp falsch sind.
Ich hoffe ihr könnt mir helfen. Danke.
Titel: Re: Farjump zum Registerwert und mit Segmentänderung
Beitrag von: Jidder am 30. June 2012, 18:26
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