Единственная причина - переменные функции: первые аргументы, извлекаемые из стека, являются «известными» для функции, и по ним можно определить, сколько других аргументов следует прочитать из стека.
Обратите внимание, что для правильной работы в таких соглашениях о вызовах очистка стека предоставляется вызывающей стороне, которая знает, сколько аргументов она выдвинула в стеке.Это немного менее эффективно, чем callee-cleanup, потому что код очистки должен быть написан после каждого вызова функции, в то время как в соглашениях о вызовах, которые не допускают использование функций с переменным числом, он может быть встроен в конце каждой функции.
Кроме этого, нет особой причины, на самом деле существует несколько соглашений о вызовах (например, Pascal , Borland Fastcall ), которые не допускают функции с переменным числом аргументов и передают параметры слева направо.