2012-03-16 3 views
1

У меня проблемы с некоторым встроенным кодом сборки. Я пытаюсь загрузить элементы из локального статического массива в регистры на платформе ARM. К сожалению, я понятия не имею, как сообщить GCC, что он должен передать указатель на массив для регистрации. Этот регистр будет использоваться для косвенной привязки к массиву.Работа с массивом в gcc inline ассемблере (ARM)

// should return argv[1] 
int test() { 
    int argv[4] = {4, 3, 2, 1}; 
    int out; 

    __asm__ volatile (
     "ldr r0, %[ARGV]" "\n\t" 
     "mov r1, #4" "\n\t" 
     "ldr r2, [r0, r1]" "\n\t" 
     "mov %[OUT], r2" 
     : [OUT] "=r" (out) 
     : [ARGV] "m" (argv) // <==== i don't know which constraint put here :/ 
     : "r0", "r1", "r2" 
    ); 

    return out; 
} 

Теперь ошибка GCC броска, и я понятия не имею, как это исправить:

Assembler messages: 
Error: invalid offset, value too big (0xFFFFFFFC) 

Thx

EDIT: Я составил его с Android NDK (арм-линукс-androideabi- г ++)

+0

Эта сборка, ссылки и работает отлично для меня, используя clang. Не уверен, что происходит для вас. Вы уверены, что в этом коде это ошибка? – mattjgalloway

+0

Я забыл сказать, что я скомпилирую его с Android NDK (arm-linux-androideabi-g ++) – zdenek

+0

Это работает для вас, если вы установите ограничение 'argv' на' 'rm" 'вместо этого? – mattjgalloway

ответ

1

Я думаю, что он должен работать так:

[ARGV] "r" (argv) 

Это говорит: «Загрузите адрес массива в регистр».

+0

Да, ты прав. Я заменяю 'LDR' на' MOV' и использую ограничение 'r', и теперь он работает нормально. Спасибо. – zdenek

1

Вам не нужно перемещать ARGV или OUT в/из регистров, это то, что ограничивает ограничение регистра.

"mov r1, #4\n\t" 
"ldr %[OUT], [%[ARGV], r1]\n\t" 
: [OUT] "=r" (out) 
: [ARGV] "r" (argv) 
: "r1" 

примечание: этот код имеет проблемы при компиляции с слишком высокими настройками оптимизации. (я не знаю, как это решить, за исключением: use -O0)

Смежные вопросы