我正在尝试在 64 位 Linux 上运行的 NASM 中实现一个数组的选择排序。
数组声明为:
section .bss
strbuf resb 10
small resb 1 ; current minimum value
排序算法本身很简单,但我觉得受到两件事的限制:可用寄存器的数量,以及无法交换立即数(即括号)
我需要跟踪未排序的数组边界、它的索引、当前最小值的位置以及它的索引。那已经是四个寄存器了。我还需要跟踪两个循环计数器,一个用于表示未排序数组边界的外循环,另一个用于每次遍历的迭代(即内循环)。那是另外两个,总共六个寄存器。
由于立即数不能相互移动,例如mov [var1], [var2]
当我需要交换两个元素时,我需要使用寄存器作为临时占位符。在跟踪哪些寄存器保存哪些信息方面,这很快变得笨拙!
以下是我迄今为止的尝试。请注意,这是触发分段错误的非工作代码。但也许你能察觉到我想要做什么,并指出我的方法哪里出了问题。
我不希望使用简化结构的宏,例如那些提供 .IF 和 .ELSE 的宏。
; ====== Sorting begins here ======
sorting:
mov edi, strbuf ; outer loop pointer
mov esi, strbuf ; inner loop pointer
mov eax, 0 ; inner loop counter
mov ebx, 0 ; outer loop counter
innerloop:
; store the value of first element in [small]
mov edx, [esi]
mov [small], edx
; compare the current small value with the value pointed by esi
mov edx, [esi]
cmp [small], edx
jg new_small
inc esi
inc eax
cmp eax, 9
jle innerloop
cmp eax, 9
jg innerloop_done
new_small:
mov [small], edx ; save the new small value
mov ecx, esi ; save its index in ecx
inc esi
inc eax
cmp eax, 9
jle innerloop
innerloop_done:
; When the inner loop is completed...
; First, do the swap
push rax
mov eax, [edi]
mov edx, [small]
mov [ecx], edx
pop rax
inc edi ; move the outer loop pointer forward
inc esi ; move the inner loop pointer forward
inc ebx ; increment the outer loop counter (the unsorted array becomes smaller)
inc eax ; increment the inner loop counter (same reason as above)
cmp ebx, 9
jle innerloop
; ====== Sorting ends here ======