Мне нужна функция, которая не клобует. ЛЮБЫЕ регистры, потому что это своего рода обработчик ошибок страницы. Благодаря предыдущему ответу, мы знаем, что этот атрибут будет поддерживаться в будущих версиях gcc, но пока не является основным.
Без этого атрибута, моя функция, которую я использую в качестве своего рода страница обработчика ошибок, которые не должен колошматить какие регистры значения выглядит следующим образом:
#define PREFIX_SIZE (14l)
__asm__ volatile ("in: \n\t"
"pushf\n\t"
"push %rbp\n\t"
"mov %rsp,%rbp\n\t"
"push %rdi\n\t"
"push %rsi\n\t"
"push %rdx\n\t"
"push %rcx\n\t"
"push %r8 \n\t"
"push %r9 \n\t"
"push %rax\n\t"
);
void page_fault_handler() {
/*
* some code here
*/
__asm__ volatile ("jmp reg_out\n\t");
}
__asm__ volatile ("reg_out: \n\t"
"leave\n\t" // what the original code was doing
"pop %rax\n\t"
"pop %r9 \n\t"
"pop %r8 \n\t"
"pop %rcx\n\t"
"pop %rdx\n\t"
"pop %rsi\n\t"
"pop %rdi\n\t"
"leave\n\t" // my leave
"popf\n\t"
"ret\n\t");
Это явно раздражает, потому что я должен назвать это адрес:
(void*)((ulong)page_fault_handler - PREFIX_SIZE)
вместо
(void*)page_fault_handler
Это также приводит к пр oblems при компиляции с флагом оптимизации -O2, поскольку он переупорядочивает метки.
Если вы заметили, я не сохранять RBX вручную здесь, потому что я составил этот код:
gcc -fcall-saved-rbx
Этот флаг компиляции заставляет компилятор сохранять и восстанавливать RBX в начале и в конце функции. Так почему же я не просто делаю это для всех регистров? Потому что это вызывает внутреннюю ошибку компилятора для rax: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79407
Можете ли вы объяснить, что вы НАСТОЯТЕЛЬНО пытаетесь сделать? Я уверен, что вы не можете заставить gcc НЕ использовать регистры в функции - конечно, не для чего-либо сложного, так как большинство инструкций в x86 требуют, чтобы один операнд был как минимум регистром. –
Я использую код сборки, чтобы вызвать эти функции. Я в порядке с ними, используя любые регистры, если они будут их восстанавливать. – user1637056
Я нашел этот флаг компиляции, который имеет значение, которое я хочу, но на весь файл: -fcall-saved-reg. Это не работает корректно в некоторых регистрах (rax, rdx) – user1637056