Пишу ОС (важно, не выйдет использовать stdarg)
Остановись на этом месте и почитай про __builtin_va_list, __builtin_va_start, __builtin_va_arg и __builtin_va_end.
Поскольку компилятор знает ABI функций с переменным числом аргументов, он так же знает, как с ними обращаться.
А если вызывать такую функцию (с аргументами "test", 'q'):
void test(char* format, ...)
{
char* ptr = format;
for (int i = -10; i < 10; i++)
{
putc(*(ptr+i));
}
}
Ожидания были таковы, что хотя бы где-то должна была появиться буква q, чего не произошло.
Ты просто искал не в том месте: вместо того чтобы двигаться по стеку ты двигался по памяти вокруг первого параметра.
Вот так нашёл бы...:
void test(char* format, ...)
{
char *ptr = (char *)&format;
for (int i = -10; i < 10; i++)
{
putc(*(ptr+i));
}
}
...если бы аргументы действительно всегда были на стеке. Но это не всегда так -- всё зависит от используемого ABI.