C не накладывает никаких ограничений на то, какие инструкции генерировать в аппаратных средствах.
Разрешается генерировать любые возможные инструкции со временем, так как семантика сгенерированного кода остается такой же, как абстрактная семантика C (определено в ISO 9899).
Компилятор преобразует код C во многие промежуточные языки (комбинаторы, rtl, ssa, generic, gimple и т. д. и т. д.), в частности в RTL, и оттуда генерируется аппаратно-зависимыйcode.
Вы должны изучить промежуточные языки, чтобы понять, почему сгенерированный ассемблер отличается.