ARM Assembly: как передать и использовать массив указателей внутри функции ARM Assembly - PullRequest
0 голосов
/ 29 сентября 2010

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

Поскольку функции сборки ARM можно передавать только с 4 параметрами (r0 - r3), я не могу понять, как передать указатель на мое возвращаемое значение, которое станет 5-м параметром для моей функции сборки.

Итак, чтобы преодолеть это, я подумал о том, чтобы поместить все 4 указателя в массив указателей, чтобы у меня было еще 3 свободных места, используя которые я также могу передать указатель на свое возвращаемое значение.

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

Вот пример того, что я пытаюсь сделать.

Программа

#include<stdio.h>

void  _my_arm_asm(float32_t *);

float32_t data_array[100][100];

void main()
{
       float32_t *ptr1, *ptr2, *ptr3, *ptr4;

        ptr1 = \\ data_array[value] + (some value);
        ptr2 = \\ data_array[value] + (some other value);
        ptr3 = \\ data_array[value] + (some other value);
        ptr4 = \\ data_array[value] + (some other value);

       float32_t *array_pointers[4];
       array_pointers[0] = ptr1;
       array_pointers[1] = ptr2;
       array_pointers[2] = ptr3;
       array_pointers[3] = ptr4;

       float32x4_t result;

       _my_arm_asm(array_pointers, &result);

        ....
        ....
        ....
       return 0;


}



.text
    .global _my_arm_asm

_my_arm_asm:
            #r0: Pointer to my array of pointers
            #r1: Pointer to my result

        push   {r4-r11, lr}

        # How to access the array of pointers?

        # I previously tried this, is this the right way to do it?

        # mov r4, #0
        # vld4.32 {d0, d1, d2, d3}, [r0, r4]
        # add r4, r4, #1
        # vld4.32 {d4, d5, d6, d7}, [r0, r4] 
        # add r4, r4, #1
        # vld4.32 {d8, d9, d10, d11}, [r0, r4] 
        # add r4, r4, #1
        # vld4.32 {d12, d13, d14, d15}, [r0, r4] 


        ....
        ....
        ....

        pop    {r4-r11, pc}

Ответы [ 2 ]

4 голосов
/ 29 сентября 2010

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

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

Глава 5 (Базовый стандарт вызова процедур) "Стандарта вызова процедур для архитектуры ARM" должна содержать точные детали. На первый взгляд, это довольно сложно (потому что есть много деталей по выравниванию, размеру аргумента и т. Д.), Но я думаю, что для ваших целей это сводится к тому, что 5-й аргумент функции get помещается в стек.

Конечно, как вы предлагаете в своем вопросе, вы могли бы избежать всего этого, упаковав 4 указателя в структуру и передав указатель на структуру - в своей процедуре сборки вы просто загружаете этот указатель структуры в регистр и используете его чтобы в свою очередь загрузить указатели, которые вам действительно нужны.

Я думаю, что сборка ARM может выглядеть примерно так:

                 // r0 has the 1st parameter
ldr r4, [r0]     // get array_pointers[0] into r4
// ...

ldr r5, [r0, #4] // get array_pointers[1] into r5
// ...

ldr r6, [r0, #8] // get array_pointers[2] into r6

Вы также можете использовать инструкцию «загрузить несколько», чтобы получить все 4 указателя за один выстрел, но я не уверен, что вы можете зарегистрировать требования / ограничения использования.

3 голосов
/ 29 сентября 2010

Пятый и последующие параметры (при условии, что параметры int-size) передаются в стек.Т.е. пятый параметр будет доступен как [SP], шестой как [SP, # 4] и так далее.Прочитайте Стандарт вызова процедуры для архитектуры ARM для подробных объяснений.
Тем не менее, вам не нужно использовать сборку, чтобы использовать NEON.Посмотрите NEON встроенные , которые позволяют вам выполнять все операции с использованием простого кода C.

...