Синтаксис ljmp во встроенной сборке gcc

Я думал об использовании дальнего перехода для установки регистра сегмента кода (CS). Чтобы понять, почему я это делаю и почему я вообще имею дело с сегментацией, потребуется некоторое время, так что потерпите меня и считайте это академическим упражнением. Я не могу понять синтаксис правильно.

Error: suffix or operands invalid for 'ljmp'

Я знаю, что глупо помещать cs в другой регистр, но я решил попробовать, так как использование %0 не работает (регистр ax тоже не работает).

Я смотрю на какой-то код, который отлично компилируется, и это сводит меня с ума, так как я думал, что ljmp будет таким же: __asm volatile ( "lcall $0x8, $far_call" );

Я бы, конечно, приветствовал другие хакерские способы воздействия на регистр CS.

void set_cs(u16 cs) {
    __asm__ volatile (
        "mov %0, %%ax \n\t"
        "ljmp %%ax, $fake_label \n\t"
        "fake_label: \n\t"
        :
        : "r" (cs)
        : "ax"
    );
}

person Duc    schedule 06.11.2009    source источник
comment
Встроенная сборка — заноза в заднице; почему бы просто не написать настоящие ассемблерные процедуры в реальных ассемблерных файлах?   -  person Carl Norum    schedule 06.11.2009
comment
Вы уверены, что его можно кодировать с помощью регистров вместо непосредственных, прочитав руководство Intel? Я до сих пор не могу расшифровать эту штуку :-)   -  person Ciro Santilli 新疆再教育营六四事件ۍ    schedule 16.10.2015


Ответы (1)


Казалось бы, ljmp требует констант для работы, в то время как это генерирует больше кода и, очевидно, не особенно безопасно, похоже, это работает, когда я ввожу значение, которое не является текущим значением cs, приложение аварийно завершает работу. Вместо этого он использует непосредственное значение:

#define set_cs( cs ) asm volatile ( "ljmp %0, $fake_label \n\t fake_label: \n\t" :: "i"(cs) )

Это не так элегантно, как я полагаю, вы хотели, и полностью зависит от того, что вы пытаетесь сделать. Я не могу представить, чтобы это когда-либо было полезно или даже работало, если вы компилируете это для работы под linux/windows.

person Dave    schedule 25.11.2009
comment
Дальние переходы используются в автономном коде (например, в коде операционной системы) для указания селекторов сегментов кода (даже в x86_64 они используются для указания уровня привилегий, то есть пространства ядра/пользователя). Я согласен, это не имеет особого смысла в коде пользовательского пространства... - person vyudh; 14.06.2013