1.Тут надо смотреть, чтобы не зацепить регистры уже используемые компилятором. В доке есть описание, какие и как используються.
Поэому наиболее безопасно пойти путем (2).
Как компромис можно сделать функии с С вызовом и ассемблерным телом
Код
int foo(char)
{
asm{.......}
}
Тогда работу со стеком берет на себя компилятор, а логику работы программист.
Впрочем напоследок скажу - gcc оптимизирует достаточно хорошо, и ввязываться в изыски с асмом особой надобности нет. Напишите функцию на С, скомпилируйте и просмотрите листинг - в 90% случаев выкинуть оттуда будет нечего.