Все ссылки на статьи и ролики моего канала Old Programmer:
Программирование. Тематическое оглавление моего Zen-канала (Old Programmer)
Соображения по поводу функций с переменным числом параметров
Захотелось поделится некоторыми соображениями по поводу функций с переменным число параметров. В языке C в старом его 32-битовом варианте использовались функции с многоточием, например f(n, p1, ...). При этом n - количество параметров, p1 - первый параметр. Количество всех параметров определяется n. А далее взяв указатель на параметр p1 (&p1) можно путем инкрементирования получить все остальные параметры, ведь общее их количество мы знаем. В 64-битовой системе такое не проходит. Ведь часть параметров передается через стек. В руководствах предлагается использовать тип va_list и макрос va_start (stdarg.h). Можно в дальнейшем об этом поговорить отдельно.
Сегодня мне бы хотелось изложить идею, которую я до конца не реализовал, но хотел бы. А может быть вы реализуете. Идея основывается на встроенном ассемблере. О нем речь будет еще впереди, а здесь я приведу только готовое решение.
Вы помните, что в Linux 64 первые шесть параметров передаются через rdi, rsi, rdx, rcx, r8, r9, а остальные через стек. К стеку можно получить доступ через rbp (в начале функции значение rsp помещается rbp). Так вот в языке C можно использовать ассемблерные вставки. Например,
__asm__ __volatile__ ("mov %%rdx, %0"
:"=rm"(z)
:
);
При этом переменная z получает содержимое регистра rdx. Т.е. значение третьего параметра. Или
__asm__ __volatile__ ("mov 24(%%rbp), %0"
:"=rm"(z)
:
);
И переменная z получает значение 8-ого параметра (ну если он есть).
В следующей статье по этому вопросу показано, как решить проблему с помощью дополнительного ассемблерного модуля. См. также статью, в которой данная проблема решается с помощью макроса.
Вот такая не хитрая технология. Пока, и подписываемся на мой канал Old Programmer.