assembly 合并已排序数组:我无法比较数组中的值

owfi6suc  于 2023-05-13  发布在  其他
关注(0)|答案(1)|浏览(109)

我有一个问题,要求我合并两个数组,每个值都是int,所以4个字节长,成为一个数组。数组中的值按从高到低的顺序排列,因此需要是新数组。
数组都以0结尾,新数组也应该以0结尾。
所有3个数组都是通过将标签获取到内存中,然后新数组需要保存在标签的地址 mergedArray 中。
但是,旧数组中的值可以出现多次,而新数组中的每个值最多只能出现一次。
我写的代码似乎工作正常,而数组没有出现一次以上的值,但失败,一旦任何值出现一次以上。
我试着将原始数组中的值与新数组中的值进行比较,如果它们相同,则跳过它。
但是在运行了一些测试之后,似乎添加或删除该比较对代码没有任何影响。
代码如下:

.global _start

.section .text
_start:
    mov $array1, %rax
    mov $array2, %rcx
    mov $mergedArray, %r8

    xor %r14,%r14
    
loopcheck: #checks if arrays are finished

    movl (%rax), %r9d 
    movl (%rcx), %r10d 
    movl (%r8), %r11d

    testl %r9d, %r9d
    jz rest_of_array2

    
    testl %r10d, %r10d
    jz rest_of_array1
    
loop: #the main loop
    cmp %r10d, %r9d 
    jg add_r9d
    jmp add_r10d
    

add_r9d: #add rax value
    cmp %r11d,%r9d
    jz remove_current_r9d
    
    mov %r9d, (%r8)

    lea 4(%r8), %r14
    mov %r14 , %r8
    

remove_current_r9d: #adv rax

    lea 4(%rax), %r14
    mov %r14, %rax
    jmp loopcheck

add_r10d: #add rcx value
    cmp %r11d, %r10d
    jz remove_current_r10d
    mov %r10d, (%r8)

    lea 4(%r8),%r14
    mov %r14, %r8

remove_current_r10d: #adv rcx
    lea 4(%rcx), %r14
    mov %r14, %rcx
    jmp loopcheck

rest_of_array2: #adding the rest of array 2 once array 1 is finished
    testl %r10d, %r10d
    jz end
    cmp %r10d,%r11d
    jz finish_loop2
    movl %r10d, (%r8)

    lea 4(%r8),%r14
    mov %r14, %r8

finish_loop2:
    lea 4(%rcx), %r14
    mov %r14 ,%rcx

    movl (%rcx), %r10d 
    movl (%r8), %r11d

    jmp rest_of_array2


rest_of_array1: #adding the rest of array 1 once array 2 is finished
    testl %r9d,%r9d
    jz end
    cmp %r9d,%r11d
    jz finish_loop1
    movl %r9d, (%r8)

    lea 4(%r8),%r14
    mov %r14, %r8

finish_loop1:
    lea 4(%rax),%r14
    mov %r14 ,%rax

    movl (%rax), %r9d 
    movl (%r8), %r11d

    jmp rest_of_array1

end: #ennd
    xor %r14,%r14
    mov %r14, (%r8)
xvw2m8pv

xvw2m8pv1#

我试着将原始数组中的值与新数组中的值进行比较,如果它们相同,则跳过它。
但是在运行了一些测试之后,似乎添加或删除该比较对代码没有任何影响。

逻辑错误

“我在新数组中的值”并不完全是你现在在程序中使用的!(三次出现)指令movl (%r8), %r11d * 确实 * 从为目标数组保留的内存中读取,但在尚未写入的数组部分执行此操作。实际上,%R11D寄存器会不断地被分配垃圾,或者如果幸运的话,你会得到最初填充程序的.BSS部分的零。
精确执行以下步骤:

  • 从程序中删除(出现三次)指令movl (%r8), %r11d
  • 在目标数组中存储值时,还需要在%R11D寄存器中存储同一值的副本。因此,您需要追加到(两次出现的)指令movl %r9d, (%r8)movl %r9d, %r11d和(两次出现的)指令movl %r10d, (%r8)movl %r10d, %r11d
  • 要开始,请将%R11D寄存器初始化为0。您可以将冗余的xor %r14,%r14替换为xor %r11d, %r11d
end: #ennd
    xor %r14,%r14
    mov %r14, (%r8)
  • array 1 * 和 * array 2 * 包含双字,并以最后的0结束,这也是一个双字。

因此,不要以q字0结束 mergedArray,而是以d字0结束。

xor  %r14d, %r14d
mov  %r14d, (%r8)

相关问题