Как использовать C определяет в ассемблере ARM - PullRequest
7 голосов
/ 19 июня 2010

Как я могу использовать внешние определения, такие как LONG_MIN и LONG_MAX в коде ассемблера ARM?

Допустим, my_arm.h выглядит так:

int my_arm(int foo);

Допустим, у меня есть my_main.c следующим образом:

...
#include <limits.h>   
#include "my_arm.h"
...
int main (int argc, char *argv[])
{
  int foo=0;
...
  printf("My arm assembler function returns (%d)\n", my_arm(foo));
...
}

И my_arm.s выглядит так:

  .text
  .align 2
  .global my_arm
  .type   my_arm, %function
my_arm:
    ...
    ADDS r1, r1, r2
    BVS overflow
    ...
overflow: 
    LDR r0, LONG_MAX @ this is probably wrong, how to do it correctly?
    BX lr @ return with max value

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

Я компилирую с arm-linux-gnueabi-gcc версии 4.3.2

==================

ОБНОВЛЕНИЕ: цените предложения!К сожалению, у меня все еще возникают проблемы с синтаксисом.

Сначала я сделал небольшой заголовочный файл mylimits.h (сейчас в том же каталоге, что и .S)

#define MY_LONG_MIN 0x80000000

в my_arm.Sя добавил следующее:

...
.include "mylimits.h"
...
ldr r7, =MY_LONG_MIN @ when it was working it was ldr r7, =0x80000000
...

Две проблемы с этим подходом.

Сначала самая большая проблема: символ MY_LONG_MIN не распознается ... так что что-то все еще не правильно

Второе: синтаксис для .include не позволяет мне включать <limits.h>, я должен был бы добавить, что в mylimits.h, кажется немного глупым, но я полагаю, это нормально:)

Любые указатели?

У меня есть доступ к Руководству разработчика систем ARM Проектирование и оптимизация системного программного обеспечения [2004] и Справочное руководство по архитектуре ARM [2000], однако моя цель - семейство XScale-IXP42x rev 2 (v5l).

Ответы [ 5 ]

11 голосов
/ 19 июня 2010

Часто расширение файла в нижнем регистре .s подразумевает, что ассемблер не должен проходить через препроцессор c, тогда как расширение .S в верхнем регистре подразумевает, что оно должно. Однако ваш компилятор должен следовать этому соглашению (обычно это делают порты gcc), поэтому проверьте его документацию.

(РЕДАКТИРОВАТЬ: обратите внимание, что это означает, что вы можете использовать директивы #include - но помните, что большинство файлов, которые вы включаете, обычно не будут действительными ассемблерами (если они не состоят полностью из #define идионов), поэтому вам, возможно, придется напишите свой собственный заголовок, который есть)


изменить 5 лет спустя:

Обратите внимание, что компилятор armcc v5 следует этому поведению в Linux ... но не в Windows.

2 голосов
/ 02 июля 2010

Если вы используете gcc и его ассемблер, это просто: назовите файл с конечным .S, затем добавьте в начале #include <limits.h> и используйте везде, где вам нужна константа, например ldr r0, SOMETHING;Я делал тесты с x86, так как это то, что у меня есть, но то же самое работает, так как это функция gcc.

1 голос
/ 28 июня 2010

То, что я в итоге сделал, это:

в my_main.c

#include <limits.h>
...
int my_LONG_MAX=LONG_MAX;

затем в my_arm.S

ldr r8, =my_LONG_MAX 
ldr r10, [r8] 

Это выглядит конвульсивно, и это(плюс выгоды переносимости сомнительны в этом подходе).

Должен быть способ доступа к LONG_MAX непосредственно в сборке.Такой способ я бы с радостью принял как полный ответ.

0 голосов
/ 27 октября 2015

используйте --cpreproc для опции armasm и добавьте

#include "my_arm.h"

в my_arm.s.

это работает для Keil ARM

0 голосов
/ 20 июня 2010

Я видел, что простая подача gcc ассемблерный источник против газа позволит вам делать C как в ассемблере. На самом деле немного страшно, когда вы сталкиваетесь с ситуациями, когда вы должны использовать gcc в качестве переднего плана для газа, чтобы заставить что-то работать, но это другая история.

...