assembly 数组1和数组2是反向排序的数组,我写了一个程序把这些数组合并成一个新的反向排序的数组

e5nszbig  于 2023-10-19  发布在  其他
关注(0)|答案(1)|浏览(127)

数组1和数组2是反向排序的数组。
我写了一个程序,将这些数组合并为一个新的反向排序数组。

.global _start
.section .data
 array1: .int 6,4,0
 array2: .int 5,3,0
 mergedArray: .zero 20
.section .text
_start:
    # set up the input array pointers
    leal array1, %eax   # pointer to the first element of array1
    leal array2, %ebx   # pointer to the first element of array2
    # set up the output array pointer
    leal mergedArray, %ecx   # pointer to the first element of output_array
    # set up the loop counters
    movl $0, %edx    # counter for array1
    movl $0, %esi    # counter for array2

loop:
    # compare the current elements of the two arrays
    movl (%eax,%edx,4), %edi   # load the current element of array1 into %edi
    movl (%ebx,%esi,4), %ebp   # load the current element of array2 into %ebp
    cmpl %edi, %ebp            # compare the two elements
    jg elementArray1Greater    # if the element from array1 is greater than the element from array1, add it to the output array
    jl elementArray2Greater    # if the element from array2 is greater than the element from array2, add it to the output array
    jmp equal   

elementArray1Greater:
     movl %edi, (%ecx,%edx,4)   # add the current element of array1 to the output array
     leal 4(%ecx), %ecx
     addl $4, %edx              # advance the counter for array1
     jmp loop

elementArray2Greater:
     movl %ebp, (%ecx,%esi,4)   # add the current element of array2 to the output array
     leal 4(%ecx), %ecx
     addl $4, %esi              # advance the counter for array2
     jmp loop

equal:  cmpl $0, %edi
        je finish
        movl %edi, (%ecx,%edx,4)   # add the current element of array1 to the output array
        leal 4(%ecx), %ecx
        addl $4, %edx
        addl $4, %esi
        jmp loop 

finish:     movl %ebp, (%ecx,%esi,4)   # add the current element of array2 to the output array
    # exit
    movl $0, %eax
    movl $1, %ebx
    int $0x80

我得到SF错误:

Program received signal SIGSEGV, Segmentation fault.
0x00000000004000df in elementArray1Greater ()

我使用objdump命令并获取(SF线是黄线):

登记册资料:

我认为问题是leal 4(%ecx), %ecx命令,但当我摆脱它,仍然有一个SF错误。
我不能解决这个问题,感谢任何帮助。

jgovgodb

jgovgodb1#

我认为问题是leal 4(%ecx), %ecx命令[sic],但当我摆脱它时,仍然存在SF错误。
这并不是说 * 那个 * 特定的指令,而是你将它与缩放索引寻址模式相结合的事实,使你在 mergedArray 中迈出了巨大的步伐,从而触及了不属于数组的内存。

源数组

如果您打算使用缩放索引寻址模式遍历源数组,则需要以简单的增量1调整关联的索引寄存器%EDX / %EBP。将4加到索引寄存器并乘以4将使您在这些数组之外寻址内存。当然,更简单的解决方案是避免使用缩放索引寻址模式,只需将4添加到指针寄存器%EAX / %EBX。

目标数组

你正在使用一个缩放索引寻址模式遍历目标数组,为此你使用了两个索引寄存器%EDX / %EBP,它们与目标数组没有任何关系!此外,由于您已经向指针寄存器%ECX添加了4,因此根本不需要使用缩放索引寻址模式。

修改算法

leal  array1, %eax        # pointer to array1
  leal  array2, %ebx        # pointer to array2
  leal  mergedArray, %ecx   # pointer to mergedArray

loop:
  movl  (%eax), %edi        # load current element array1 into %edi
  movl  (%ebx), %ebp        # load current element array2 into %ebp
  cmpl  %edi, %ebp          # compare the two elements
  jg    elementArray1Greater
  jl    elementArray2Greater

equal:
  testl %edi, %edi
  jz    finish
  leal  4(%ebx), %ebx       # Advance in array2
  ---- fall through for smaller footprint (less code) ----
elementArray1Greater:
  movl  %edi, (%ecx)        # add element of array1 to output array
  leal  4(%eax), %eax       # Advance in array1
  leal  4(%ecx), %ecx       # Advance in mergedArray
  jmp   loop

elementArray2Greater:
  movl  %ebp, (%ecx)        # add element of array2 to output array
  leal  4(%ebx), %ebx       # Advance in array2
  leal  4(%ecx), %ecx       # Advance in mergedArray
  jmp   loop

finish:
  movl  %edi, (%ecx)        # Add 0 to mergedArray

也测试一下

array1: .int 6,4,0
array2: .int 5,3,0

确保你还检查了两个数组都包含一个不是终止零的相同数字的情况:

array1: .int 6,3,0
array2: .int 5,3,0

相关问题