I am attempting to reverse an array2 however my program seg faults and ends right at
mov eax, dword [edi] . theoretically this should work just fine. please any insight or alternative method/recommendations, my professor and pupils are equally stumped. Anything is much appreciated, this is my code:

global _start:

section .bss

section .data

    array dd 1,2,3,4,5

    array2 dd 1,2,3,4,5

section .text

    global _start:


    ;first element in array

    mov esi,    dword [array2]  

    ;second element in array

    mov edi,    dword [array+16]

    ;counter reg    

    mov ecx,    edi
    ;dec    edi
    call reverseloop

    mov eax, 1
    mov ebx, 0
    int 80H


    mov     eax,    dword [edi]
    mov ebx,    dword [esi]

    ;swap elements

    mov dword [edi],    eax 
    mov dword [esi],    ebx
    add esi,    4
    sub edi,    4
    cmp esi,    edi
    jb  reverseloop

There are a number of faults that a program can encounter at runtime, and segfault is a very specific one. I'm not going to give you the answer straight out since this sounds like it could be a homework question, but if you read up on the basics of what causes a segfault, you should be able to spot where you're going wrong. Check out this extract from Wikipedia

Segmentation faults have various causes, and are a common problem in programs written in the C programming language, where they arise primarily due to errors in use of pointers for virtual memory addressing, particularly illegal access.

Illegal access is the key term here. You can only access memory you've allocated in your program.

I'd like to add to what Assembly Guy has said. The notion of "memory allocation" and "segment limits" are almost universally confused with each other. Certainly it is true that in "protected" mode operating systems (Windows, Linux, Unix, Mac) that they amount to almost the same thing. The user never gets to set segment limits directly - this is done for him when requesting memory allocations. However, in DOS this is not the case. While it is certainly true that the default segment size in DOS was 65K, it was possible to set it to whatever you liked as long it was compatible with the number of bits in the addressing registers.

With this in mind, a segfault is, by definition, a processor exception caused by any attempt to access a location whose address is outside the segment limits defined by the segment descriptor currently in use.

This is true in real mode (i.e. in DOS) where the segment register actually contains a physical address, and in virtual mode (Windows, Linux, etc) where the segment register only contains a segment descriptor (that is a handle into a kernel maintained segment table).

mov esi, dword [array2]
mov edi, dword [array+16]

Your problem lies in these 2 lines. I suggest that you have a really hard look at exactly what is happening here. Use the debugger to examine the contents of esi and dsi after these instructions. Do you see the problem? If not, trace into the swapping routine with the debugger.

I believe that you already found the problem when you said that:

mov eax, dword [edi] Segfaults.

What I really can't comprehend is that neither your teachers or your pupils did not see this right away.