Hacker News new | ask | show | jobs
by cnvogel 4536 days ago
Here's what you can do to add a "complicated" constant stored elsewhere, in hand-crafted assembler:

    add_something:        ; function starts here (argument r0 == some number)
	ldr r1, __tmp     ; get complicated constant, store in r1
	add r0, r0, r1    ; do the addition r0 = r0 + r1
	bx lr            ; == return result (in r0)
    __tmp:
	.word 0x12345678  ; store complicated constant here
You can play with your compiler, if you call gcc as "gcc -Os -S -o- file.c" if will spit out generated assembler code (-S) on stdout "-o-" for the c-code in file.c.

(but then, gcc prefers to have 4 "compact" adds, instead of loading a constant...)

    $ cat dummy.c
    int
    add_random_number(int a)
    {
            return a + 0x12345678; /* guaranteed to be random */
    }

    $ arm-none-eabi-gcc -S -o- -Os dummy.c
    (...)
    add_random_number:
            @ Function supports interworking.
            @ args = 0, pretend = 0, frame = 0
            @ frame_needed = 0, uses_anonymous_args = 0
            @ link register save eliminated.
            add     r0, r0, #301989888
            add     r0, r0, #3424256
            add     r0, r0, #5696
            add     r0, r0, #56
            bx      lr
2 comments

In at least the ADT assembler and gas a few years back, the assembler provided syntactic sugar:

    ldr r0,=0x123456578
assembles to

    ldr r0,pc+xxx
    ... and then somewhere later ...
    .word 0x12345678
The assembler had some default places it would put constant pools (end of a module?), or you could explicitly tell it to generate a constant pool if the default place would be outside the limit of the pc-relative addressing mode.
From my experience on x86, GCC's -Os isn't that great - looks like it's the same for ARM.