英文:
Merging sorted arrays: I can't compare values from arrays
问题
我明白了,以下是你要的代码的翻译:
.global _start
.section .text
_start:
mov $array1, %rax
mov $array2, %rcx
mov $mergedArray, %r8
xor %r14,%r14
loopcheck: #检查数组是否结束
movl (%rax), %r9d
movl (%rcx), %r10d
movl (%r8), %r11d
testl %r9d, %r9d
jz rest_of_array2
testl %r10d, %r10d
jz rest_of_array1
loop: #主循环
cmp %r10d, %r9d
jg add_r9d
jmp add_r10d
add_r9d: #添加rax的值
cmp %r11d,%r9d
jz remove_current_r9d
mov %r9d, (%r8)
lea 4(%r8), %r14
mov %r14 , %r8
remove_current_r9d: #推进rax
lea 4(%rax), %r14
mov %r14, %rax
jmp loopcheck
add_r10d: #添加rcx的值
cmp %r11d, %r10d
jz remove_current_r10d
mov %r10d, (%r8)
lea 4(%r8),%r14
mov %r14, %r8
remove_current_r10d: #推进rcx
lea 4(%rcx), %r14
mov %r14, %rcx
jmp loopcheck
rest_of_array2: #一旦数组1完成,添加数组2的其余部分
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: #一旦数组2完成,添加数组1的其余部分
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: #结束
xor %r14,%r14
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:
.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)
答案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)
array1和array2包含双字,并以一个最终的双字0结尾。因此,不要用qword 0结束mergedArray,而应该用dword 0结束。
xor %r14d, %r14d
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) instructionmovl %r10d, (%r8)
movl %r10d, %r11d
. -
To get started, initialize the %R11D register to 0. You can replace that redundant
xor %r14,%r14
byxor %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.
xor %r14d, %r14d
mov %r14d, (%r8)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论