NASM 组装插入排序
我是汇编语言的新手,但我仍然坚持这项任务。我需要插入排序汇编语言方面的帮助。我在汇编代码中没有得到 array[j+1] := array[j]
部分。
我的任务是:
编写一个汇编语言程序,使用插入排序算法对字节数组 (a) (a = {7, 5, 2, 3, 6}) 进行排序。请在内存中分配数组大小为 size = 5。
插入排序背后的基本原理很简单:将一个新数字插入到已排序数组的适当位置。为了应用这个算法,我们从一个空数组开始。然后插入第一个数字。现在数组已按排序顺序排列,只有一个元素。接下来将第二个数字插入到适当的位置。这会产生大小为 2 的排序数组。重复此过程,直到插入所有数字。该算法的伪代码如下所示,假设数组索引以 0 开头:
Insertion Sort (array, size)
for (i = 1; i < size −1; i + +) do
temp := array[i]
j := i −1
while ((temp < array[j]) and (j ≥0)) do
array[j + 1] := array[j]
j := j −1
end while
array[j + 1] := temp
end for
这里,索引 i 指向要插入的数字。 i 左边的数组是按排序顺序排列的。要插入的数字是位于索引 i 或其右侧的数字。下一个要插入的数字位于 i 处。
这是我得到的:
segment .data
array db 7,5,2,3,6
size db 5
Sorted times 5 db 0
segment .text
global main
main:
mov rsi, [Sorted]
; mov edx,[size]
sub edx,4 ; size -1
mov ecx,1 ;for (i = 1;
for: cmp edx,ecx ; i< size - 1; i++)
je finish ; i = 0 then exit
movsx rbx, byte[array + rcx] ; temp = array[i]
mov rax, rcx ; j = i - 1
sub rax,1
while: ;while ( temp < array[j] && j >= 0)
cmp rax,0 ; j >= 0?
jl end_while
cmp rbx,[array + rax] ; temp < array[j]?
jae end_while
next:
mov r8, [array + rax + 1] ;????
mov r9, [array + rax] ;????
mov r8,r9 ; array[j+1] := array[j]
mov rsi,r8
dec rax ; j = j -1
inc rcx
jmp
end_while:
mov [Sorted + rax -1] ,rbx ; array[j + 1] = temp
inc rcx
jmp for
finish:
I'm new to assembly language but I'm still stuck on this assignment. I need help with Insertion Sort assembly language. I don't get the part array[j+1] := array[j]
in assembly code.
My assignment is:
Write an assembly language program to sort an array (a) of byte (a = {7, 5, 2, 3, 6}) using the Insertion Sort algorithm. Please allocate the array size as size = 5 in memory.
The basic principle behind the insertion sort is simple: insert a new number into the sorted array in its proper place. To apply this algorithm, we start with an empty array. Then insert the first number. Now the array is in sorted order with just one element. Next insert the second number in its proper place. This results in a sorted array of size two. Repeat this process until all the numbers are inserted. The pseudocode for this algorithm, shown below, assumes that the array index starts with 0:
Insertion Sort (array, size)
for (i = 1; i < size −1; i + +) do
temp := array[i]
j := i −1
while ((temp < array[j]) and (j ≥0)) do
array[j + 1] := array[j]
j := j −1
end while
array[j + 1] := temp
end for
Here, index i points to the number to be inserted. The array to the left of i is in sorted order. The numbers to be inserted are the ones located at or to the right of index i. The next number to be inserted is at i.
Here is what I got:
segment .data
array db 7,5,2,3,6
size db 5
Sorted times 5 db 0
segment .text
global main
main:
mov rsi, [Sorted]
; mov edx,[size]
sub edx,4 ; size -1
mov ecx,1 ;for (i = 1;
for: cmp edx,ecx ; i< size - 1; i++)
je finish ; i = 0 then exit
movsx rbx, byte[array + rcx] ; temp = array[i]
mov rax, rcx ; j = i - 1
sub rax,1
while: ;while ( temp < array[j] && j >= 0)
cmp rax,0 ; j >= 0?
jl end_while
cmp rbx,[array + rax] ; temp < array[j]?
jae end_while
next:
mov r8, [array + rax + 1] ;????
mov r9, [array + rax] ;????
mov r8,r9 ; array[j+1] := array[j]
mov rsi,r8
dec rax ; j = j -1
inc rcx
jmp
end_while:
mov [Sorted + rax -1] ,rbx ; array[j + 1] = temp
inc rcx
jmp for
finish:
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
伪代码执行就地插入排序,而汇编代码选择将排序后的元素放在其他位置(不修改原始数组)。这是一个有效的选择,但是元素的比较应该在已排序的数组中完成,而不是像在未排序的数组中所做的那样!
汇编代码中有很多错误。
mov rsi, [Sorted]
应该做什么?在您使用的 NASM 中,这将从内存中加载 8 个字节。也许您打算加载已排序数组的地址,那么它必须是mov rsi, Sorted
或lea rsi, [Sorted]
。 (或者甚至与 RIP 相关......)如果您将注释符号保留在
中; mov edx,[size]
没有希望建立正确的迭代计数。第一次从源数组中获取元素时,您使用的是
ECX=1
。对于某些高级语言来说这可能没问题,但在汇编中我们使用数组的偏移量(并且始终以字节为单位计数)。您应该已初始化ECX=0
。因为您的数组包含字节大小的元素,所以像
cmp rbx,[array + rax]
这样的指令将比较 7 个字节太多!只需使用cmp bl,...
。类似地,
mov [Sorted + rax -1] ,rbx ; array[j + 1] = temp
将覆盖 8 个字节,而您应该只插入一个字节。另外,我们将其视为拼写错误,但根据下面的注释,rax - 1
确实应该是rax + 1
。。这是我的插入排序版本。我根本没有遵循伪代码。我研究了任务描述中提供的非常清晰的解释,并仅基于此编写了此解决方案。某些高级语言的代码版本对于尝试理解手头的任务当然很有用,但在我看来,将高级代码紧密地转换为汇编语言是朝着错误方向迈出的一步。你必须在组装时思考。这和你学外语没有什么不同...
The pseudocode does an in-place insertion sort, whereas your assembly code chooses to put the sorted elements elsewhere (not modifying the original array). That's a valid choice but then the comparing of elements should be done in the sorted array and not like you are doing in the unsorted array!
There are a lot of errors in the assembly code.
What is
mov rsi, [Sorted]
supposed to do? In NASM that you are using, this will load 8 bytes from memory. Perhaps you meant to load the address of the sorted array and then it would have to bemov rsi, Sorted
orlea rsi, [Sorted]
. (Or even RIP-relative...)If you keep the comment sign in
; mov edx,[size]
there's no hope to establish the correct iteration count.The very first time that you fetch an element from the source array, you are using
ECX=1
. That might be fine is some high level language, but in assembly we use an offset into an array (and always count in bytes). You should have initializedECX=0
.Because your array contains byte-sized elements, an instruction like
cmp rbx,[array + rax]
will be comparing 7 bytes too many! Just usecmp bl, ...
.Similarly,
mov [Sorted + rax -1] ,rbx ; array[j + 1] = temp
will be overwriting 8 bytes where you should only be inserting a single byte. Also let's consider it a typo, butrax - 1
should really berax + 1
in accordance with the comment that follows.This is my version of this insertion sort. I did not follow the pseudocode at all. I studied the very clear explanation that was provided in the task description and wrote this solution solely based on that. Versions of the code in some high level language are certainly useful in trying to understand the task at hand, but IMO closely translating the high level code to assembly is a step in the wrong direction. You got to think in assembly. That's no different from how you learn a foreign language...