反向数组 X86 AT&T 语法

Reverse Array X86 AT&T Syntax

我正在用 Assembly 编写一个程序,它在开头声明了 2 个数组和 3 个函数,它们是:

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

现在程序获取这些数组并打印每个对应位置的 2 个数组的乘积并打印它们。 然后打印 Array1。 然后打印 Array1 Reversed。 然后它应该取反转数组并再次调用乘法函数并打印第一个数组反转位置和第二个数组位置的乘积,第二个数组永远不会改变。(源代码中的数组值)

我在反转数组并尝试将反转的第一个数组和第二个数组相乘后遇到问题。

下面是我程序的输出

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

所以最后这个输出显然不是array1和array2的乘积

正如您在下面的代码中看到的(PS 我已经尝试用 movq 代替 leaq)我的反向数组在 %rax 中返回,我将它放入 %rcx 这一切都很好而且花花公子,因为我成功地在下面打印出一个反向数组

#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 [=12=], %rax

然而,一旦我再次调用 multQuads,我得到了奇怪的结果,我确信我的反向数组没有正确地移动到寄存器中。原始数组是一个常量,因此很简单,但我认为我将所有值压入堆栈并以相反的顺序弹出它们以某种方式改变了结构。或者我打错了。源代码如下:

.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 [=13=], %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 [=13=], %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 [=13=], %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 [=13=], %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 [=13=], %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    [=13=], %rax

    # purposely not pushing any caller save registers.
    callq printf


    movq [=13=], %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    [=13=], %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    [=13=], %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    [=13=], %rax
    call printf



    movq [=13=], %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    [=13=], %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    [=13=], %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    [=13=], %rbx        #array index
    movq    [=13=], %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

如果 multQuad 函数第一次工作并且我可以正确打印出反向数组,那么我想问题一定是在我调用 multQuad 并设置寄存器之前就出现了

我在 printQArray 中丢失了数组

只有一行!!