Соглашения о сборке x86_64, сохраняющие регистры аргументов

Я пишу некоторую сборку x86_64 для вызова функции C. Моя функция C принимает 1 аргумент, поэтому сборка помещает аргумент в %rdi, В документе ABI pdf (ссылка ниже) говорится, что остальные 6 регистров аргументов (rsi, rdx, rcx, r8, r9) не сохраняются при вызовах функций. Тем не менее, так как моя функция C занимает только один long аргумент, есть ли у меня какие-либо гарантии о том, будет или нет функция C перекрывать другие 5 регистров? Мое предположение состояло в том, что регистры аргументов закрываются только при изменении значения аргумента:

void foo(int a, int b) {
    a++; /* %rdi will be changed, but %rsi won't be changed when control returns. */
}

Я спрашиваю, потому что я хотел бы сохранить значения других 5 регистров аргументов через мой вызов функции C (без необходимости явного извлечения / извлечения их из стека вручную).

x86_64 ABI - http://www.x86-64.org/documentation/abi-0.99.pdf

2 ответа

Решение

Там нет гарантии. Вам нужно будет сохранить их в стеке, чтобы они не изменились. Будут ли они изменены, будет зависеть от компилятора.

Если вы хотите как-то убедиться, что они не изменены, вы можете написать функцию в сборке.

Посмотрите на таблицу на странице 21. В ней есть столбец "Сохранено Да / Нет" для всех регистров. И он говорит "Нет" для всех регистров, используемых для передачи параметров.

Независимо от того, передаете вы аргументы или нет, регистры аргументов не обязательно должны быть сохранены. Скорее всего, вы не получите свои параметры обратно.

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