Sint
Sint

Reputation: 1620

How to use C defines in ARM assembler

How can I use external defines such as LONG_MIN and LONG_MAX in ARM assembler code?

Let's say my_arm.h looks like this:

int my_arm(int foo);

Let's say I have a my_main.c as follows:

...
#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));
...
}

And my_arm.s looks like this:

  .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

The second to last line, I am not sure how to load correctly, I vaguely remember reading somewhere, that I had to define LONG_MAX in .global, but can't find the link to a working example anymore.

I am compiling with arm-linux-gnueabi-gcc version 4.3.2

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

UPDATE: Appreciate the suggestions! Unfortunately, I am still having trouble with syntax.

First, I made a little header file mylimits.h (for now in same dir as .S)

#define MY_LONG_MIN 0x80000000

in my_arm.S i added the following:

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

Two problems with this approach.

First the biggest problem: the symbol MY_LONG_MIN is not recognized...so something is still not right

Second: syntax for .include does not let me include <limits.h>, I would have to add that in mylimits.h, seems a bit kludgy, but I suppose, that is ok :)

Any pointers?

I have access to ARM System Developer’s Guide Designing and Optimizing System Software[2004] and ARM Architecture Reference Manual[2000], my target is XScale-IXP42x Family rev 2 (v5l) though.

Upvotes: 8

Views: 17879

Answers (5)

James
James

Reputation: 25543

Often the lowercase file extension .s implies that assembler should not be passed through the c preprocessor, whereas the uppercase extension .S implies that it should. It's up to your compiler to follow this convention though (gcc ports normally do), so check its documentation.

(EDIT: note that this means you can use #include directives - but remember that most of the files you would include would not normally be valid assembler (unless they consist entirely of #defineitions), so you may have to write your own header that is)


edit 5 years later:

Note that the armcc v5 compiler follows this behaviour under linux... but not on windows.

Upvotes: 11

netawater
netawater

Reputation: 15844

use --cpreproc for armasm option and add

#include "my_arm.h"

into my_arm.s.

it works for Keil ARM

Upvotes: 0

ShinTakezou
ShinTakezou

Reputation: 9671

If you are using gcc and its assembler, it is straightforward: name the file with final .S, then add at the beginning #include <limits.h> and use wherever you need the constant, e.g. ldr r0, SOMETHING; I did tests with x86 since it is what I have, but the same works since it is a gcc feature.

Upvotes: 2

Sint
Sint

Reputation: 1620

What I ended up doing is this:

in my_main.c

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

then in my_arm.S

ldr r8, =my_LONG_MAX 
ldr r10, [r8] 

It looks convuluted and it is(plus the portability gains are questionable in this approach).

There must be a way to access LONG_MAX directly in assembly. Such a way I would gladly accept as the full answer.

Upvotes: 1

old_timer
old_timer

Reputation: 71556

I have seen simply feeding gcc the assembler source vs gas will allow you to do C like things in assembler. It is actually a bit scary when you come across situations where you must use gcc as a front end to gas to get something to work, but that is another story.

Upvotes: 0

Related Questions