在x86程序集中交换数组值时的值错误

时间:2012-11-05 18:38:00

标签: arrays assembly x86 quicksort

我正在使用x86程序集中的quicksort,我需要交换数组A [pivot]和A [j]的两个元素,但我甚至无法为数组索引赋值,更不用说交换元素了

数组是这样分配的:

A:      .long   2,1,8,6,12

我原来的交换方案根本不起作用所以我把它简化为了解我的问题所在。我已经尝试了很多方法来获得正确的结果,但都会导致错误的值或分段错误

    movl    A(,%ebx,4), %eax            #eax = A[pivot]
    movl    A(,%edi,4), %edx            #edx = A[j]


                                        #ebx = pivot = 0
                                        #edi = j = 1

    pushl   %eax
    pushl   $test7                      #"A[pivot] = %d"
    call    printf
    addl    $8, %esp                    # A[0] = 2 

    pushl   %edx
    pushl   $test8                      #"A[j] = %d"
    call    printf
    addl    $8, %esp                   #A[1] = 1

此代码段返回:

A[pivot]         = 2 
A[j]             = -143535296 

A [pivot] = A [0] = 2,所以这是正确的,但是 A [j] = A [1] = 1

当%ebx和%edi是两个数组索引时,这是引用数组元素的正确方法,以查看其内容或更改其值。

无法弄清楚我做错了什么,任何帮助都会受到赞赏。

编辑:另外,如果我使用A(,[index],4)作为printf参数,它会显示正确的值。

edit1:我意识到为什么我的printf语句不正确,我改为代码,它返回了似乎是正确的内存地址。 addr [A] = 134513652和addr [A + 1] = 134513656.虽然我仍然存在更改数组值的原始问题,但在执行此操作时我仍然遇到分段错误:

    leal    A(,%ebx,4), %ecx        # ecx = addr[A[0]]          
    movl    A(,%edi,4), %edx        # edx = A[1]
    movl    %edx, (%ecx)            # (ecx) = edx

1 个答案:

答案 0 :(得分:1)

您应该阅读有关调用约定的内容。被调用者和调用者保存寄存器。在许多ia32调用约定中,EAX,ECX和EDX是调用者保存寄存器。这意味着一个电话 - 在你的情况下第一次打印电话 - 可能会改变它们的价值。它被称为调用者保存,因为您作为调用者负责保存值,例如使用push / pop指令。您的示例也可以通过使用其中一个被调用者保存的寄存器来修复。