0

I feel like this is a simple question, but I am not able to find it anywhere on the internet or in any of my textbooks or powerpoints of my class so far. I have a project that I cannot start without first creating an array, so I am just asking how to translate

int A[10];

(A[10] of course being an array of size 10)

into Armv8 assembly code

edit: I honestly don't understand the questions in response to my question, it is being compiled in DS-5 if that helps

  • 2
    Depends on which assembler and whether you want a global or a local. In GNU assembler you can do something like `.lcomm A, 40` for example. – Jester Feb 28 '22 at 12:27
  • 1
    At global scope (static storage)? Or inside a function (automatic storage = stack space)? The answer is completely different depending on which it is. Of course either way you can just look at compiler-generated asm, especially for a file containing only that C declaration if you want global scope. [How to remove "noise" from GCC/clang assembly output?](https://stackoverflow.com/q/38552116) – Peter Cordes Feb 28 '22 at 12:42
  • 1
    With ARMv8, do you mean AArch64 code? Also, what assembler are you programming for? The GNU assembler? The Keil assembler? Lastly, what storage class would you like your array to reside in? Static storage? Automatic storage (i.e. stack)? Or something else? – fuz Feb 28 '22 at 15:52

1 Answers1

1

For local arrays on the stack, it's pretty much same as other architectures. Just subtract the stack pointer and store your values there.

For int a[10], sub sp, sp, #48 will allocate your array on the stack. As Nate Eldredge mentioned in a comment, ARMv8 requires 16-byte stack alignment from hardware, so you cannot write sub sp, sp, #40. You can store some value like str r, [sp] for *a = r, and str r, [sp, #4] for a[1] = r, and so on.

For global arrays, just define a symbol in .bss and allocate enough space for it.

.bss
a:
    .zero 40

This allocates a global array with 10 32-bit ints.

Such global arrays belong to a certain section in an executable file. You can make whatever section you like with custom read-write-executable qualities, but usually, non-zero-initialized modifiable data goes in the .data section, while modifiable all-zero data goes in the .bss section. See here for basic details.


You can always check Godbolt to see how each statement in C is translated to assembly. Check with and without optimizations, both will give you different interesting information.

For example, here's how Clang with -O3 translates this simple code in C.

int a[10];

void f() {
    a[1] = 2;
}

void g() {
    volatile int b[10];
    b[3] = 4;
}

/*
  .text
f:
        adrp    x8, a+4
        mov     w9, #2
        str     w9, [x8, :lo12:a+4]
        ret
g:
        sub     sp, sp, #16
        mov     w8, #4
        str     w8, [sp, #12]
        add     sp, sp, #16
        ret

  .bss
a:
        .zero   40
*/

Godbolt with directives not filtered so the section switching is visible. (The block above has directives filtered out, except for .section directives.)

See how a local array and a global array are allocated and accessed differently. I believe now you have more specific questions in case you still have a problem.

xiver77
  • 2,162
  • 1
  • 2
  • 12
  • For global arrays, you have to put the symbol in `.bss` (or worse `.data`), not along with code in `.text`. That would be a bug because it's not declared `const` in the C. (And yes this may seem obvious to us, but so are the parts you did answer.) – Peter Cordes Mar 01 '22 at 11:44
  • @PeterCordes I added details. – xiver77 Mar 01 '22 at 12:17
  • @NateEldredge Sorry, fixed that part. – xiver77 Mar 01 '22 at 17:00