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.