【发布时间】:2012-10-25 15:36:31
【问题描述】:
我正在 x86 汇编中进行快速排序,我需要交换数组 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
这个 sn-p 返回:
A[pivot] = 2
A[j] = -143535296
A[pivot] = A[0] = 2,所以这是正确的,但是 A[j] = A[1] = 1
当 %ebx 和 %edi 是两个数组索引以查看它们的内容或更改它们的值时,这是引用数组元素的正确方法吗?
无法弄清楚我做错了什么,任何帮助将不胜感激。
edit:另外,如果我使用 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
【问题讨论】:
-
尝试使用操作码
leal(加载有效地址,长)进行一些测试,看看您是否获得了彼此接近的地址。我不知道它会如何发生,但可能会有一些关于段寄存器的恶作剧。 -
你的 printf 电话正在破坏
edx。调用函数时要小心,要么保存易失性寄存器,要么使用被调用者保存的寄存器,如 esi、edi、ebx。 -
我使用了 'leal A, %eax' 和 'leal A, %edx' 没有位移然后打印 %eax 和 %edx 这给了我 '%eax = 134513652 ',正确A 的地址,以及完全关闭的 '%edx = -143224000'。肯定会发生一些奇怪的事情,如果相关的话,我只使用 32 位寄存器。编辑:好的,没有意识到 printf 会更改解释第二次 printf 调用结果的寄存器值。
-
我得到了地址
addr[A] = 134513652和addr[A+1] = 134513656,所以我想它们是正确的内存地址,然后我想我可以这样做来更改值leal A(,%ebx,4), %eaxmovl A(,%edi,4), %edxmovl %edx, (%eax),但这只是返回一个分段错误。 -
好的。您已经发布了您的调试代码,但是您用于交换的代码是什么,那个不起作用的代码是什么?
标签: arrays assembly x86 quicksort