Могу ли я использовать регистр в качестве счетчика цикла?

Поскольку соглашение о вызове функции указывает, какие регистры сохранены, можно ли использовать регистр в качестве счетчика цикла?

Сначала я подумал, что 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 - это регистры, которые вы должны сохранить перед их использованием и восстановить после их использования (также называемые энергонезависимыми регистрами). Вы можете положиться на эти регистры, имеющие то же значение после вызова, что и до вызова...

...

Смотрите также:

Другие вопросы по тегам