Das sind zwei unterschiedliche Speicherarten, die Du verwendest:
Im ersten Fall wird statisch - also zur Compilezeit - Speicherplatz reserviert. In Deinem Fall müsste das .bss Block Storage Segment, d.h. uninitialisierter Speicher im RAM sein.
Im zweiten Fall wird der Speicher erst bei Aufruf der Funktion auf dem Stack reserviert. Das kann der Linker nur dann prüfen, wenn man ihm vorher sagt, wie groß der Stack maximal ist. Da die Variable ebenfalls nicht initialisert ist reicht es, in Assembler den Stackpointer entsprechend zu verschieben und sich nur die Anfangsadresse des Bereiches auf dem Stack zu merken. Dass das auf der Zielhardware nicht passt, kann der Compiler in dem Fall nicht wissen - und dem Linker sagt's ja niemand.