简体   繁体   中英

Reverse Array X86 AT&T Syntax

I'm writing a program in Assembly that has has 2 arrays declared at the beginning and 3 functions, which are:

printQArray(int size, long *array1)
invertArray(int size, long *array1)
multQuad(int size, long *array1, long *array2)

Now the program takes these arrays and prints the products of the 2 arrays for each corresponding positions and prints them. Then it prints Array1. Then it prints Array1 Reversed. Then it should take the reversed array and call the multiplication function again and print the product of the positions of 1st array reversed and the 2nd array which never changes.(Array values in source code)

I'm having problems after I reverse the array and attempt to multiply the reversed 1st array and 2nd array.

The following is the output of my program

Products
200
-925
1386
-2928
9375
64350

Elements in QArray1
10
25
33
48
125
550

Elements in QArray1
550
125
48
33
25
10

Products
0
-1036
-31584
44896
0
0

So this last output is clearly not the products of array1 reversed and array2

As you can see in my code below(PS I have already tried movq in place of leaq) my reversed array is being returned in %rax and I put it into %rcx This is all fine and dandy because I successfully print out a reversed array below

#PRINT Inverted ARRAY1   void printArray(int size, long *array1);
movq    $sizeQArrays, %rax
movq    (%rax), %rdi        #sizeQArrays to %rdi (parameter 1)
leaq    (%rcx), %rsi        #put reversed array into rsi
call printQArray
movq $0, %rax

However once I call the multQuads again I get weird results, I'm confident my reversed array isn't getting moved into the register properly. The original array was a constant and thus simple but I think me pushing all the value's onto the stack and popping them back off in reverse order has changed the structure somehow. Or maybe I have a typo. Source Code below:

.section .rodata
.LC1: .string "Products\n"

.LC3: .string "Elements in QArray1\n"

.LC4: .string "%i\n"

.LC5: .string "\n"

.data
sizeQArrays:
.quad 6
QArray1:
.quad 10
.quad 25
.quad 33
.quad 48
.quad 125
.quad 550
QArray2:
.quad 20
.quad -37
.quad 42
.quad -61
.quad 75
.quad 117

.globl main
    .type   main, @function
.globl printQArray
    .type   printQArray, @function
.globl multQuads
    .type   multQuads, @function
.globl invertArray
    .type   invertArray, @function
.text
main:
    pushq %rbp      #stack housekeeping
    movq %rsp, %rbp

    #order of calls: quad print invert print quad

    #MULTQUADS void multQuads(int size, long *array1, long *array2)
    movq $sizeQArrays, %rax
    movq (%rax), %rdi  #1st param
        movq $QArray1, %rsi #2nd Param
    movq $QArray2, %rdx #3rd Param

    call multQuads

    movq $0, %rax


    #PRINT ARRAY1    void printArray(int size, long *array1);
    movq    $sizeQArrays, %rax
    movq    (%rax), %rdi        #sizeQArrays to %rdi (parameter 1)
    movq    $QArray1, %rsi      #address of QArray1 to %rsi (parameter 2)

    #purposely not pushing anything because I have not put anything in registers
    #except parameters and I will be putting new values there after return

    call printQArray

    movq $0, %rax


    #InvertArray void invertArray(long size, long *array1)
    movq $sizeQArrays, %rax
    movq (%rax), %rdi  #1st param
        movq $QArray1, %rsi #2nd Param
    call invertArray
    leaq (%rax), %rcx       #put inverted array into %rcx
    movq $0, %rax       #set %rax back to 0



    #PRINT Inverted ARRAY1   void printArray(int size, long *array1);

    movq    $sizeQArrays, %rax
    movq    (%rax), %rdi        #sizeQArrays to %rdi (parameter 1)
    movq    %rcx, %rsi      #put reversed array into rsi



    call printQArray

    movq $0, %rax





    #MULTQUADS W/ REVERSED ARRAY void multQuads(int size, long *array1, long *array2);

    movq $sizeQArrays, %rax
    movq (%rax), %rdi  #1st param
        movq %rcx, %rsi    #inversed array as 2nd param
    movq $QArray2, %rdx #3rd Param

    call multQuads

    movq $0, %rax


    #END of main

    leave
    ret

.size   main, .-main

#printQArray prints an array of 8 byte values
# the size of the array is passed in %rdi,
# a pointer to the beginning of the array is passed in %rsi


printQArray:

    pushq   %rbp
    movq    %rsp, %rbp

    pushq   %r12
    pushq   %r13
    pushq   %rbx


    movq    %rdi, %r12  #copy size to %r12
    movq    %rsi, %r13  #copy array pointer to %r13

    # print array title
    movq    $.LC3, %rdi
    movq    $0, %rax

    # purposely not pushing any caller save registers.
    callq printf


    movq $0, %rbx       #array index

printQArrayLoop:
    movq    (%r13, %rbx, 8), %rsi   #element of array in 2nd parameter register
    movq    $.LC4, %rdi     #format literal in 1st parameter register
    movq    $0, %rax

    #purposely not pushing any caller save registers
    callq printf

    incq    %rbx            #increment index

    decq    %r12            #decrement count

    jle printQArrayExit
    jmp printQArrayLoop

printQArrayExit:
    # print final \n
    movq    $.LC5, %rdi     #parameter 1
    movq    $0, %rax

    call    printf

    popq    %rbx
    popq    %r13
    popq    %r12
    leave
    ret
.size   printQArray, .-printQArray







multQuads:

    pushq   %rbp
    movq    %rsp, %rbp

    pushq   %r12
    pushq   %r13
    pushq   %r14
    pushq   %rbx


    movq    %rdi, %r12  #copy size to %r12
    movq    %rsi, %r13  #copy array1 pointer to %r13
    movq    %rdx, %r14  #copy array2 pointer to %r14

    # print "Products"
    movq    $.LC1, %rdi
    movq    $0, %rax
    call printf



    movq $0, %rbx       #array index

multQuadLoop:
    movq    (%r13, %rbx, 8), %rsi   #element of array in 2nd parameter register
    movq    (%r14, %rbx, 8), %rdx   #element of array in 3rd parameter register
    movq    $.LC4, %rdi     #format literal in 1st parameter register
    imulq   %rdx, %rsi      #insert product into second parameter
    movq    $0, %rax

    callq printf

    incq    %rbx            #increment index

    decq    %r12            #decrement count

    jle multQuadExit
    jmp multQuadLoop

multQuadExit:
    # print final \n
    movq    $.LC5, %rdi     #parameter 1
    movq    $0, %rax

    call    printf

    popq    %rbx
    popq    %r13
    popq    %r12
    popq    %r14
    leave
    ret
.size   multQuad, .-multQuad


invertArray:

    pushq   %rbp
    movq    %rsp, %rbp

    pushq   %r12    #size
    pushq   %r13    #array pointer
    pushq   %rbx    #array index 
    pushq   %r9 #holder
    pushq   %r10    #holder
    push    %r14



    movq    %rdi, %r12  #copy size to %r12
    movq    %rdi, %r9

    movq    %rsi, %r13  #copy array pointer to %r13
    movq    $0, %rbx        #array index
    movq    $0, %r10

invertArrayLoop:
    pushq   (%r13, %rbx, 8) #push elements of array onto stack

    incq    %rbx            #increment index

    decq    %r12            #decrement count

    jle reverseArray
    jmp invertArrayLoop


reverseArray:
    popq %r14
    movq %r14, (%r13, %r10, 8)

    incq %r10

    decq %r9

    subq %r12, %r9
    jle     invertArrayExit
    jmp reverseArray



invertArrayExit:
    movq %r13, %rax
    popq    %r14
    popq    %r10
    popq    %r9
    popq    %rbx
    popq    %r13
    popq    %r12
    leave
    ret
.size   invertArray, .-invertArray

If the multQuad function works the 1st time and I can print out the reversed array properly then I imagine the problem must be right before im calling multQuad and setting the registers

I was losing the array in printQArray

It was just one line!!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM