Find the number in an array which is closest to an given number
mov edi, edi    ; Index of the element with the smallest value.



An error here. You want to zero this register. Use xor



A better strategy will be to simply subtract without looking at which number is the largest and then later take the absolute value of the difference.

    mov     eax, [nums + 4 * esi]
    sub     eax, ebx
    jnl     IsPositive
    neg     eax
IsPositive:
    cmp     eax, edx ; Compare the result to the current smallest value.
    jnb     prepare_next
    mov     edx, eax
    mov     edi, esi
prepare_next:


Less code and less register usage!



A further optimization will come from not using ECX as a loop counter. You can determine if the loop is completed by looking at the ESI array index.

    xor     esi, esi         ;Start at index 0
check_next:
    ...
    inc     esi
    cmp     esi, (nums_end - nums) / 4
    jb      check_next




In stead of branching, you could use one of the conditional forms of mov.
Same code size but faster. Having less labels is also nicer.

    cmp     eax, edx ; Compare the result to the current smallest value.
    cmovb   edx, eax
    cmovb   edi, esi


About coding style.


mov eax, dword[nums + 4 * edi]



Does your assembler requires you to write this redundant mention of the size?
Do you get an error if you write it shorter?

    mov     eax, [nums + 4 * edi]