Могу ли я использовать регистр в качестве счетчика цикла?
Поскольку соглашение о вызове функции указывает, какие регистры сохранены, можно ли использовать регистр в качестве счетчика цикла?
Сначала я подумал, что ecx
регистр используется в качестве счетчика цикла, но после обнаружения, что stdcall
Функция, которую я использовал, не сохранила значение ecx
Я думал иначе.
Существует ли регистр, который гарантированно (по крайней мере, по большей части используемым соглашениям о вызовах) сохраняется?
Примечание: у меня нет проблем с использованием переменной стека в качестве счетчика цикла, я просто хочу убедиться, что это единственный способ.
2 ответа
Вы можете использовать любой регистр общего назначения, а иногда и другие, в качестве счетчика цикла (конечно, не указатель стека ☺).
Либо вы используете один, чтобы зациклить вручную, то есть заменить...
loop label
… с…
dec ebp
jnz label
… Что в любом случае быстрее (потому что AMD (а затем и Intel, когда они догнали МГц) искусственно замедлила loop
В противном случае Windows® и некоторое скомпилированное программное обеспечение Turbo Pascal вышли из строя.
Или вы просто сохраняете счетчик между:
label:
push ecx
call func
pop ecx
loop label
Оба являются стандартными стратегиями.
Существует ли регистр, который гарантированно (по крайней мере, по большей части используемым соглашениям о вызовах) будет сохранен?
Вы можете выбрать любой свободный регистр в своем собственном коде, если ваш код цикла не будет вызывать какую-либо внешнюю сущность.
Если ваш код цикла вызовет внешнюю сущность, где единственным гарантированным контрактом является ABI и соглашение о вызовах, то вы должны сохранить / восстановить свои регистры и сделать выбор регистров в каждом конкретном случае.
Цитирую отличную статью Agner Fog: Соглашения о вызовах для различных компиляторов C++ и операционных систем:
6 Зарегистрируйте использование
Правила использования регистров зависят от операционной системы, как показано в таблице 4. Скретч-регистры - это регистры, которые можно использовать для временного хранения без ограничений (также называемые регистрами сохранения вызовов или энергозависимыми регистрами). Регистры сохранения Callee - это регистры, которые вы должны сохранить перед их использованием и восстановить после их использования (также называемые энергонезависимыми регистрами). Вы можете положиться на эти регистры, имеющие то же значение после вызова, что и до вызова...
...
Смотрите также: