ret
вообще ничего не делает с x0
.ret
- это то, как вы пишете mov pc, x30
в AArch64 .(x30 - это регистр ссылок, где bl
(ответвление и ссылка) помещает обратный адрес.)
Ваш вопрос действительно о соглашениях о вызовах. Функции, вызывающие друг друга, должны согласовыватьсяо том, как передаются аргументы и возвращаются возвращаемые значения.
В стандартном соглашении о вызовах AArch64
x0
является первым регистром передачи аргументов для целочисленных / указательных аргументов. x0
- это (первый) регистр возвращаемых значений для целочисленных значений / указателей.
Так что, когда вы ret
в функции, отличной от void
, вызывающая сторона будет обрабатыватьвсе, что находится в x0
как (часть) возвращаемого значения.(Если ваша функция не возвращает float
или double
, то вызывающая сторона будет искать в s0
или d0
, предполагая, что ABI находится в плавающем плавающем поле.)
Если вы объявите свою функцию как возвращающую большойСтруктура по значению, вызывающая сторона передаст вам указатель в качестве первого аргумента, увеличивая «нормальные» аргументы на 1. Затем вы должны будете сохранить возвращаемое значение в указанной памяти.(И, возможно, также верните указатель, который вы передали в x0
, но я не проверял, является ли это требованием или нет.)
TL: DR, если вы ret
ничего не делаете сx0
, ваша функция эффективно возвращает первое целое число / указатель arg.