Вызов функции

Первые четыре аргумента передаются в первые четыре регистра ARM — r0, r1, r2 и r3. Все последующие кладутся в стек — sp, sp + 4, sp + 8… Возвращаемое значение функции записывается в регистр r0.

Данное описание справедливо только для целочисленных переменных. Переменные, занимающие два слова, например, long long или double, передаются в два соседних регистра, а возвращаемое значение передается в r0, r1.

Вызов функции с четырьмя и менее аргументами более эффективен, так как в противном случае и вызывающий, и вызываемый должны получить доступ к стеку для некоторых переменных. Если в функции вам требуется больше 4 аргументов, то более эффективно использовать структуру.

Следующий пример иллюстрирует преимущества использования структур.

uint32_t solver_1(uint32_t *x, uint32_t *y, uint32_t *z,
uint32_t c, uint32_t *arr) {
    // do something
    return 0;
}
// ...
typedef struct {
    uint32_t *x;
    uint32_t *y;
    uint32_t *z;
} COORDINATES_t;
​
uint32_t solver_2(COORDINATES_t *cor, uint32_t c, uint8_t *arr) {
    // do something
    return 0;
}

Выигрыш происходит из-за того, что во втором случае нужно настроить всего три регистра против четырех в первом с последующей работой с медленным стеком.


Изменено: