合并已排序的数组:我无法比较来自数组的值。

huangapple go评论84阅读模式
英文:

Merging sorted arrays: I can't compare values from arrays

问题

我明白了,以下是你要的代码的翻译:

  1. .global _start
  2. .section .text
  3. _start:
  4. mov $array1, %rax
  5. mov $array2, %rcx
  6. mov $mergedArray, %r8
  7. xor %r14,%r14
  8. loopcheck: #检查数组是否结束
  9. movl (%rax), %r9d
  10. movl (%rcx), %r10d
  11. movl (%r8), %r11d
  12. testl %r9d, %r9d
  13. jz rest_of_array2
  14. testl %r10d, %r10d
  15. jz rest_of_array1
  16. loop: #主循环
  17. cmp %r10d, %r9d
  18. jg add_r9d
  19. jmp add_r10d
  20. add_r9d: #添加rax的值
  21. cmp %r11d,%r9d
  22. jz remove_current_r9d
  23. mov %r9d, (%r8)
  24. lea 4(%r8), %r14
  25. mov %r14 , %r8
  26. remove_current_r9d: #推进rax
  27. lea 4(%rax), %r14
  28. mov %r14, %rax
  29. jmp loopcheck
  30. add_r10d: #添加rcx的值
  31. cmp %r11d, %r10d
  32. jz remove_current_r10d
  33. mov %r10d, (%r8)
  34. lea 4(%r8),%r14
  35. mov %r14, %r8
  36. remove_current_r10d: #推进rcx
  37. lea 4(%rcx), %r14
  38. mov %r14, %rcx
  39. jmp loopcheck
  40. rest_of_array2: #一旦数组1完成,添加数组2的其余部分
  41. testl %r10d, %r10d
  42. jz end
  43. cmp %r10d,%r11d
  44. jz finish_loop2
  45. movl %r10d, (%r8)
  46. lea 4(%r8),%r14
  47. mov %r14, %r8
  48. finish_loop2:
  49. lea 4(%rcx), %r14
  50. mov %r14 ,%rcx
  51. movl (%rcx), %r10d
  52. movl (%r8), %r11d
  53. jmp rest_of_array2
  54. rest_of_array1: #一旦数组2完成,添加数组1的其余部分
  55. testl %r9d,%r9d
  56. jz end
  57. cmp %r9d,%r11d
  58. jz finish_loop1
  59. movl %r9d, (%r8)
  60. lea 4(%r8),%r14
  61. mov %r14, %r8
  62. finish_loop1:
  63. lea 4(%rax),%r14
  64. mov %r14 ,%rax
  65. movl (%rax), %r9d
  66. movl (%r8), %r11d
  67. jmp rest_of_array1
  68. end: #结束
  69. xor %r14,%r14
  70. mov %r14, (%r8)
英文:

I have a question that asks me to merge two arrays with each value being an int, so 4 bytes long, into one array. The values in the arrays are in order from highest to lowest and so needs to be the new array.
The arrays end with 0 both, and so should the new one.

All 3 of the arrays I get by getting a label to memory, and then the new array needs to be saved in the address of the label mergedArray.

But, the values in the old arrays can appear more than once, while the new array needs to have each value once at most.

The code I wrote seems to work fine while the arrays don't have values appear more than once, but fail once any value appear more than once.

I tried to compare the value I have in the original array to the value I have in the new array, and then skip it if they are the same.

But after running some tests, it seems that adding, or removing that comparison makes no difference to the code.

Here's the code:

  1. .global _start
  2. .section .text
  3. _start:
  4. mov $array1, %rax
  5. mov $array2, %rcx
  6. mov $mergedArray, %r8
  7. xor %r14,%r14
  8. loopcheck: #checks if arrays are finished
  9. movl (%rax), %r9d
  10. movl (%rcx), %r10d
  11. movl (%r8), %r11d
  12. testl %r9d, %r9d
  13. jz rest_of_array2
  14. testl %r10d, %r10d
  15. jz rest_of_array1
  16. loop: #the main loop
  17. cmp %r10d, %r9d
  18. jg add_r9d
  19. jmp add_r10d
  20. add_r9d: #add rax value
  21. cmp %r11d,%r9d
  22. jz remove_current_r9d
  23. mov %r9d, (%r8)
  24. lea 4(%r8), %r14
  25. mov %r14 , %r8
  26. remove_current_r9d: #adv rax
  27. lea 4(%rax), %r14
  28. mov %r14, %rax
  29. jmp loopcheck
  30. add_r10d: #add rcx value
  31. cmp %r11d, %r10d
  32. jz remove_current_r10d
  33. mov %r10d, (%r8)
  34. lea 4(%r8),%r14
  35. mov %r14, %r8
  36. remove_current_r10d: #adv rcx
  37. lea 4(%rcx), %r14
  38. mov %r14, %rcx
  39. jmp loopcheck
  40. rest_of_array2: #adding the rest of array 2 once array 1 is finished
  41. testl %r10d, %r10d
  42. jz end
  43. cmp %r10d,%r11d
  44. jz finish_loop2
  45. movl %r10d, (%r8)
  46. lea 4(%r8),%r14
  47. mov %r14, %r8
  48. finish_loop2:
  49. lea 4(%rcx), %r14
  50. mov %r14 ,%rcx
  51. movl (%rcx), %r10d
  52. movl (%r8), %r11d
  53. jmp rest_of_array2
  54. rest_of_array1: #adding the rest of array 1 once array 2 is finished
  55. testl %r9d,%r9d
  56. jz end
  57. cmp %r9d,%r11d
  58. jz finish_loop1
  59. movl %r9d, (%r8)
  60. lea 4(%r8),%r14
  61. mov %r14, %r8
  62. finish_loop1:
  63. lea 4(%rax),%r14
  64. mov %r14 ,%rax
  65. movl (%rax), %r9d
  66. movl (%r8), %r11d
  67. jmp rest_of_array1
  68. end: #ennd
  69. xor %r14,%r14
  70. mov %r14, (%r8)

答案1

得分: 1

> 我尝试比较原始数组中的值与新数组中的值,如果它们相同,就跳过它。

> 但是经过一些测试后,似乎添加或删除该比较对代码没有影响。

逻辑错误

“我在新数组中的值”并不完全是您当前在程序中使用的内容!(三次出现的)指令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)

array1array2包含双字,并以一个最终的双字0结尾。因此,不要用qword 0结束mergedArray,而应该用dword 0结束。

  1. xor %r14d, %r14d
  2. mov %r14d, (%r8)
英文:

> I tried to compare the value I have in the original array to the value I have in the new array, and then skip it if they are the same.

> But after running some tests, it seems that adding, or removing that comparison makes no difference to the code.

A logical error

"the value I have in the new array" is not quite what you are using right now in your program! The (thrice-occurring) instruction movl (%r8), %r11d does read from the memory that is reserved for the destination array, but does so on a part of the array that hasn't been written to yet. In essence, the %R11D register continually gets assigned garbage, or if you're lucky, you get the zeroes that originally populated the .BSS section of the program.

Follow these next steps precisely:

  • Remove the (thrice-occurring) instruction movl (%r8), %r11d from the program.

  • Everywhere you store a value in the destination array, you also need to store a copy of that same value in the %R11D register. So you need to append to the (twice-occurring) instruction movl %r9d, (%r8) movl %r9d, %r11d, and to the (twice-occurring) instruction movl %r10d, (%r8) movl %r10d, %r11d.

  • To get started, initialize the %R11D register to 0. You can replace that redundant xor %r14,%r14 by xor %r11d, %r11d.


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

array1 and array2 contain dwords and are terminated by a final 0 which also is a dword.
So, instead of ending mergedArray with a qword 0, have it terminate with a dword 0.

  1. xor %r14d, %r14d
  2. mov %r14d, (%r8)

huangapple
  • 本文由 发表于 2023年5月10日 18:30:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/76217348.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定