Intel 8086插入排序:跳过阵列中的数字

时间:2013-07-29 03:12:09

标签: arrays assembly intel x86-16 insertion-sort

因此,我们正在研究我们的教授向我们展示的英特尔8086插入分类代码。他希望我们弄清楚为什么代码跳过数组中的第0个元素和数组中的第3个元素来自他从网上获取的代码。

; void isort(int *a, int n)
;   sorts the first n elements of a
;
; Parameters
;   a - pointer to the array
;   n - number of elements to sorts

%define a [ebp + 8]
%define n [ebp + 12]
isort:
  enter 0, 0
  pusha

  mov ecx, 1
  for:
    mov ebx, ecx
    imul ebx, 4
    add ebx, a
    mov ebx, [ebx]

    mov edx, ecx
    dec edx

    while:
      cmp edx, 0
      jl while_quit

      mov eax, edx
      imul eax, 4
      add eax, a

      cmp ebx, [eax]
      jge while_quit

      mov esi, [eax]

      mov dword [eax + 4], esi

      dec edx
      jmp while
    while_quit:

    mov [eax], ebx

    inc ecx
    cmp ecx, n
    jl for

  popa
  leave
  ret

样本数组是{5,8,12,2,1,7}。这是为了理解8086语言,因为我们刚开始几天,我想知道是否有人可以解释如何以及可能出现的问题。

1 个答案:

答案 0 :(得分:0)

考虑ECX为1时代码将执行的操作:

  • while循环将与EBX=8EDX=0一起输入。
  • jl while_quit将不会被采用,因为EDX为0。
  • EBX[EAX]进行比较。那是;将8与a[0]进行比较,即{5},因此jge while_quit被采用。
  • mov [eax], ebxa[0]存储8个,因此您的数组现在包含{8,8,12,2,1,7}。显然不是你想要的,因为你丢失了一个原始元素。

除了代码的逻辑缺陷之外,那些imul指令完全没必要,因为你可以在x86上使用缩放索引。因此,排序代码可以简化为此(我已经验证它正确排序了数组):

mov ecx, 1
for_:
  ; esi = &a[holePos]   
  lea esi,[a + ecx*4]
  ; valueToInsert = a[holePos]
  mov ebx, [esi]

  while_:
    ; Did we reach the beginning of the array?
    cmp esi, OFFSET a
    jle while_quit

    ; valueToInsert < a[holePos-1] ?
    cmp ebx, [esi-4]
    jge while_quit

    ; a[holePos] = a[holePos-1]
    mov eax, [esi-4]
    mov [esi], eax

    ; esi = &a[holePos-1]
    sub esi,4
    jmp while_
  while_quit:

  ; a[holePos] = valueToInsert
  mov [esi], ebx

  inc ecx
  cmp ecx, 6
  jl for_

我正在使用MASM语法,但你明白了。