Cortex M7 goes to HardFault immediately after reset
In the ARM architecture machine instructions can never reside at an odd address.  The least significant address bit of all jump instructions or vector tables would therefore be 0.  Rather than just having a constant 0 bit, the designers chose to reuse address bit 0 to indicate the instruction set encoding for a jump/branch target.  A 0 indicates that the target is 32-bit ARM code and a 1 indicates that the target is Thumb code.

It appears that the problem was that the values in the vector table were even (indicating to the processor that the vectors pointed to 32-bit ARM code).  But the ARM core in the ATSAME70Q21 supports the Armv7-M ISA (which is a Thumb instruction set).  The assembler was generating thumb instructions but jumping to that code with the T bit clear caused a HardFault (even when executing a NOP).

I noticed the problem while looking at ARM document ID120114 page B1-573 which shows the Execution Program Status Register(EPSR) register.  The T bit (bit-24) indicates weather the processor is in the Thumb mode (1) or 32-bit ARM mode (0).

My assembly code originally looked like...

 .section .vectors
 vec_table:
    .word _estack
    .word Reset_Handler
...
.section .text
Reset_Handler:
    NOP
    NOP


In order to ensure that address bit 0 was set in the vector table I changed it to...

 .section .vectors
 vec_table:
    .word _estack
    .word Reset_Handler + 0x00000001
...
.section .text
Reset_Handler:
    NOP
    NOP


Now everything works.

Apparently the C programs worked fine because the compiler was already doing this.  But in my assembly programs I need to do this manually.