В C локальные переменные и параметры хранятся в регистрах и в стеке. Это означает, что, пока у вас есть свободное место в стеке, они будут помещаться туда без явного выделения.
На самом деле все программы запускаются со стеком, выделенным по умолчанию, поэтому программе на C не нужно запрашивать больше памяти.
Как работает стек? ну ... в общем есть регистр для хранения указателя на кусок памяти. Всякий раз, когда вы входите в функцию, этот регистр перемещается так, что теперь он указывает на свободную часть стека, а когда вы покидаете эту функцию, восстанавливается старое значение регистра стека.
Внутренняя работа немного сложнее, но это общая идея.