上一篇实现了简单插入排序的算法,这一篇主要实现直接插入排序算法:

S0 SEGMENT STACK
  DW 20 DUP(?)
TOP LABEL  WORD
S0 ENDS

S1 SEGMENT
TIP DB "Input ten number and separate the numbers with space:", 0DH, 0AH, 24H
ARY DW 20 DUP(0)
CRLF  DB 0DH, 0AH, 24H
N  DW 0
E  DW 0
S1 ENDS



S2 SEGMENT
  ASSUME SS:S0, DS:S1, CS:S2, ES:S1
P  PROC  FAR
  MOV AX, S0
  MOV SS, AX
  LEA SP, TOP

  MOV AX, S1
  MOV DS, AX

  MOV AX, S1
  MOV ES, AX

  LEA DX, TIP
  MOV AH, 9
  INT 21H

  LEA SI, ARY

  XOR DX, DX
  PUSH  DX
  MOV BL, 10
  MOV CX, 10

INPUT: MOV AH, 1
  INT 21H
  CMP AL, 20H ;空格分隔字符
  JE SAVE
  ;输入十进制数,将数存入SI对应的内存单元
  MOV DL, AL 
  MOV AX, [SI]
  MUL BL
  SUB DL, 30H
  ADD AL, DL
  MOV [SI], AX
  JMP INPUT
SAVE:  
  ADD SI, 2 
  LOOP  INPUT
  ;数组保存完毕

  LEA SI, ARY
  MOV DI, SI
  ADD DI, 2
  SUB SI, 2
  MOV E, SI  ;E用于存放数组的前一个地址,用来判断遍历结束
  ADD SI, 2

  XOR AX, AX ;AX用来存插入元素的地址
  MOV CX, 9  ;总循环次数

GO: MOV BX, [DI] 
  PUSH  SI ;第一个数的位置压栈
CMPA:  CMP BX, [SI]
  JA SEL
  ;小于就把AX的值存放当前要插入的位置
  MOV AX, SI
  SUB SI, 2
  CMP SI, E
  JNE CMPA
SEL:  CMP AX, 0  ;判断AX是否又被修改过,没有说明当前数比前面的数大
  JE CON

  POP SI ;取出第一个数字的位置
  ;从AX到SI这一段的所有数字往后移动一个位置
CHANGE: MOV DX, [SI]
  XCHG  DX, [SI+2]
  ;当SI表示的位置在AX前面了,说明移动完成
  MOV BP, SI
  SUB SI, 2
  CMP AX, BP 
  JNE CHANGE

  MOV SI, AX
  MOV [SI], BX
CON:  ADD DI, 2  ;继续下一次
  MOV SI, DI
  SUB SI, 2
  XOR AX, AX ;同时需要清空AX
  CALL  PRINT
  LOOP  GO


EXIT:  MOV AH, 4CH
  INT 21H

P  ENDP

;以下为十进制输出数组中的所有数
PRINT  PROC  NEAR
  PUSH  SI
  PUSH  CX
  PUSH  AX
  PUSH  DX
  LEA DX, CRLF
  MOV AH, 9
  INT 21H

  LEA SI, ARY
  MOV CX, 10
L1: MOV AX, [SI]
  MOV N, AX
  CALL  OUTPUT
  ADD SI, 2
  MOV DX, 20H
  MOV AH, 2
  INT 21H
  LOOP  L1



  POP DX
  POP AX
  POP CX
  POP SI
  RET

PRINT  ENDP

OUTPUT PROC  NEAR
  PUSH  AX
  PUSH  BX
  PUSH  CX
  PUSH  DX

  XOR CX, CX 
  MOV AX, N
  MOV BX, 10
L2: XOR DX, DX
  DIV BX
  PUSH  DX
  INC CX
  CMP AX, 0
  JNE L2

L3: POP DX
  ADD DX, 30H
  MOV AH, 2
  INT 21H
  LOOP  L3

  POP DX
  POP CX
  POP BX
  POP AX
  RET
OUTPUT ENDP

S2 ENDS
  END P