Home > Mobile >  How to declare a local array on the stack in x64 assembly?
How to declare a local array on the stack in x64 assembly?

Time:12-05

I'm trying to declare an array of "quadwords" on the stack in my x64 assembly program. I know how to do this by declaring the array in the .data segment, but I'd like to make the array local to main if possible. I know that I could probably do this with malloc and dynamic memory allocation, as well, but I'd first like to see if it's even possible to do this on the stack. My issue is that I've declared enough memory on the stack to store the array (along with some extra space just for good measure). I store initial values into the array elements, but I don't know how to 'iterate' through the indices. I'd like to sum all the values in this array, just for practice. I tried using movq to retrieve the element, offset from the array's starting index, but I can't use negative indices in 'scaled index' mode.

     ...
     subq $128, %rsp
     movq $100, -8(%rbp) # arr[0] = 100
     movq $79, -16(%rbp) # arr[1] = 79
     movq $85, -24(%rbp) # arr[2] = 85
     movq $62, -32(%rbp) # arr[3] = 62
     movq $91, -40(%rbp) # arr[4] = 91
     movq $0, -48(%rbp) # sum = 0
     movq $5, %rcx # movq i = 5
 loop:
     cmp $1, %rcx
     jz done
     movq (%rbp, %rcx, 8), %rax # I believe this line may be wrong because the array starts at index -8(%rbp), right?
     addq %rax, -48(%rbp)
     subq $1, %rcx
     jmp loop
     ...

CodePudding user response:

In this answer, I show several ways to change your code to do what you want. The first one is a minimal change to your original code to get it to work; the final one is the way I would write it.

The first example only changes the starting and ending value of rcx. It leaves the array on the stack in the unusual top-down order, and iterates over the array from the end to the beginning.

    ...
    subq $128, %rsp
    movq $100, -8(%rbp) # arr[0] = 100
    movq $79, -16(%rbp) # arr[1] = 79
    movq $85, -24(%rbp) # arr[2] = 85
    movq $62, -32(%rbp) # arr[3] = 62
    movq $91, -40(%rbp) # arr[4] = 91
    movq $0, -48(%rbp) # sum = 0
    movq $-5, %rcx
loop:
    cmp $0, %rcx
    jz done
    movq (%rbp, %rcx, 8), %rax
    addq %rax, -48(%rbp)
    addq $1, %rcx
    jmp loop

The next example places the array in memory in the usual way, with index 0 at the lowest address, and iterates from index 0 to 4. Note the offset on the load instruction to cause index 0 to access rbp-40.

    ...
    subq $128, %rsp
    movq $100, -40(%rbp) # arr[0] = 100
    movq $79, -32(%rbp) # arr[1] = 79
    movq $85, -24(%rbp) # arr[2] = 85
    movq $62, -16(%rbp) # arr[3] = 62
    movq $91, -8(%rbp) # arr[4] = 91
    movq $0, -48(%rbp) # sum = 0
    movq $0, %rcx # i = 0
loop:
    cmp $5, %rcx
    jz done
    movq -40(%rbp, %rcx, 8), %rax
    addq %rax, -48(%rbp)
    addq $1, %rcx
    jmp loop

The final example changes a few other things to match the way I would write it:

    ...
    subq $128, %rsp
    movq $100, -40(%rbp) # arr[0] = 100
    movq $79, -32(%rbp)  # arr[1] = 79
    movq $85, -24(%rbp)  # arr[2] = 85
    movq $62, -16(%rbp)  # arr[3] = 62
    movq $91, -8(%rbp)   # arr[4] = 91
    xor            
  • Related