; Guide to Assembly Language
        ; Section 8.7 Complete Program
        ; Copyright 2010, James T. Streib
        .listall
        .386
        .model flat,c
        .stack 100h
scanf     PROTO arg2:Ptr Byte, inputlist:VARARG
printf    PROTO arg1:Ptr Byte, printlist:VARARG    
        .data
msg1fmt   byte 0Ah,"%s",0
msg2fmt   byte "%s",0
msg3fmt   byte 0Ah,"%s",0Ah,0Ah,0
msg4fmt   byte "   %d",0Ah,0
msg5fmt   byte 0Ah,0
in1fmt    byte "%d",0
msg1      byte "Enter the number of integers to be input: ",0
msg2      byte "Enter an integer: ",0
msg3      byte "Sorted",0
n         sdword ?
arry      sdword 20 dup(?)
temp      sdword ?
        .code
main      proc
        INVOKE printf,ADDR msg1fmt,ADDR msg1
        INVOKE scanf,ADDR in1fmt,ADDR n
        INVOKE printf,ADDR msg5fmt
        .if n>0              ; if n <= 0, don't continue
        mov ecx,n            ; load ecx with n
        mov edi,offset arry+0 ; load address of arry into edi
        .repeat
        push ecx             ; save ecx
        INVOKE printf,ADDR msg2fmt,ADDR msg2
        INVOKE scanf,ADDR in1fmt,ADDR [edi]
        add edi,4            ; incrment edi by 4      
        pop ecx              ; restore ecx
        .untilcxz
        .if n>1              ; check >1 elements in array
        mov ecx,n            ; load ecx with n               
        dec ecx              ; loop n-1 times   
        mov esi,offset arry+0 ; load esi with address of arry
        .repeat
        push ecx             ; save ecx
        push esi             ; save address, esi now smallest
        mov edi,esi          ; load address of esi in edi
        add edi,4            ; move edi to the next element
        .repeat
        mov eax,[esi]        ; move smallest to eax to compare
        .if [edi]<eax        ; compare smallest to next
        mov esi,edi          ; save the new smallest in esi
        .endif
        add edi,4            ; move to next element to compare
        .untilcxz
        mov edi,esi          ; edi points to smallest element
        pop esi              ; esi points to the start element
        mov eax,[esi]        ; move start element to temp
        xchg eax,[edi]       ; exchange start and smallest
        mov [esi],eax        ; move smallest back to start
        add esi,4            ; move start index to next
        pop ecx              ; restore ecx to be decremented
        .untilcxz
        .endif
        INVOKE printf, ADDR msg3fmt, ADDR msg3
        mov ecx, n            ; load ecx with n
        mov esi,offset arry+0 ; load esi with address of arry
        .repeat
        push ecx             ; save ecx
        mov eax,[esi]        ; load eax with element from arry
        mov temp,eax         ; store eax in temp for output
        INVOKE printf, ADDR msg4fmt, temp
        add esi,4            ; increment esi to next element
        pop ecx              ; restore ecx
        .untilcxz
        INVOKE printf, ADDR msg5fmt
        .endif
        ret
main      endp
        end