Если вы хотите вызвать функцию C/С++ из встроенной сборки, вы можете сделать что-то вроде этого:
void callee() {}
void caller()
{
asm("call *%0" : : "r"(callee));
}
Затем GCC испускает код, который выглядит следующим образом:
movl $callee, %eax
call *%eax
Это может быть проблематично, поскольку косвенный вызов уничтожит конвейер на более старых процессорах.
Так как адрес callee
в конечном итоге является константой, можно предположить, что можно было бы использовать ограничение i
. Цитата из GCC онлайн docs:
`я '
Допускается немедленный целочисленный операнд (один с постоянным значением). Эта включает символические константы, значения будут известны только при сборке время или позже.
Если я попытаюсь использовать его так:
asm("call %0" : : "i"(callee));
Я получаю следующую ошибку от ассемблера:
Ошибка: суффикс или операнды недействительны для `call '
Это связано с тем, что GCC испускает код
call $callee
Вместо
call callee
Итак, мой вопрос заключается в том, можно ли сделать вывод GCC правильным call
.