De lo que estás hablando es de lo que se conoce en el mundo integrado como una aplicación "bare-metal". Son muy comunes para cosas como un ARM Cortex-M3 que entra (digamos) en una caja de validación de tarjeta de débito o un juguete interactivo, y no tiene suficiente memoria o capacidad para ejecutar un sistema operativo completo. Entonces, en lugar de obtener un compilador "ARM/Linux" que compilaría una aplicación para ejecutar en Linux en un procesador ARM, obtendría un compilador "ARM bare-metal" que compila cosas para ejecutar en un procesador ARM sin un sistema operativo. (Estoy usando ARM en lugar de x86 como ejemplo, porque las aplicaciones de hardware puro x86 son bastante raras en la actualidad.)
Según lo expresado en su pregunta y en las demás respuestas, su aplicación deberá hacer algunas cosas que: de lo contrario sería atendido por el sistema operativo.
En primer lugar, necesita inicializar el sistema de memoria, los vectores de interrupción y varios otros bits de la placa goo. Por lo general, esto es algo que un compilador bare-metal hará por usted, aunque si tiene una placa extraña, es posible que necesite decirle cómo hacerlo. Esto hace que las cosas vayan desde el punto donde la placa se enciende hasta el punto donde comienza la función main().
Luego, necesita interactuar con cosas fuera de la CPU y la RAM. Un sistema operativo incluye todo tipo de funciones para hacer esto: E/S de disco, salida de pantalla, entrada de teclado y mouse, redes, etc., etc., etc. Sin un sistema operativo, debes obtenerlo de otro lugar. Puede obtener algo de eso de las bibliotecas de su fabricante de hardware; por ejemplo, una placa con la que estaba jugando recientemente tiene una pantalla LED de 40x200 píxeles, y viene con una biblioteca con el código para activarla y establecer valores de píxeles individuales en ella. Y hay varias compañías que venden bibliotecas para implementar una pila TCP/IP y cosas por el estilo, para hacer networking o cosas así.
Considere, por ejemplo, que esto dificulta incluso la impresión básica. Cuando tienes un sistema operativo, printf simplemente envía un mensaje al sistema operativo que dice "pon esta cadena en la consola", y el sistema operativo encuentra la posición actual del cursor en la consola, y hace todo lo posible para descubrir qué píxeles para cambiar en la pantalla, y qué instrucciones de la CPU usar para cambiar esos píxeles, con el fin de hacer eso.
Ah, ¿y mencionamos que primero tiene que averiguar cómo obtener el programa en la CPU? Una computadora típica tiene un poco de ROM programable que cargará las instrucciones desde el momento en que se inicie. En un x86, este es el BIOS, y normalmente ya contiene un práctico programa que inicia la CPU, configura la pantalla, busca discos y carga un programa fuera del disco que encuentra. En un sistema integrado, normalmente es donde va su programa, lo que significa que necesita alguna forma de poner su programa allí. A menudo, eso significa que tiene un dispositivo llamado "depurador" que está físicamente conectado a su placa embebida que carga el programa, y también puede hacer cosas que le permiten pausar el procesador y determinar cuál es su estado, para que pueda dar un paso a través de su programa como si lo estuviera ejecutando en un depurador de software en su computadora. Pero yo divago.
De todos modos, para responder a su segunda pregunta, este ejecutable que usted crearía es algo que se almacenará en esa ROM en su placa embebida, o quizás simplemente guarde un poco de ella en la ROM (que es, después de todo, bastante pequeño) y almacena el resto en una unidad de memoria flash, y el bit en ROM incluiría las instrucciones para extraer el resto de la memoria USB. Probablemente se almacenaría como un archivo en su computadora principal (es decir, la computadora Linux o Windows donde la está creando), pero eso es solo para almacenamiento, no se ejecutaría allí.
Notarás que cuando tienes muchas de estas bibliotecas juntas, están haciendo bastante de lo que hace un sistema operativo, y hay una especie de espacio entre la pila de bibliotecas y una verdadera operación sistema. En ese espacio va lo que se llama RTOS: "sistema operativo en tiempo real". Los más pequeños son simplemente colecciones de bibliotecas que trabajan juntas para hacer todas las cosas del sistema operativo, y a veces también incluyen cosas para que pueda ejecutar múltiples hilos a la vez (y luego puede tener diferentes hilos que actúen como diferentes programas) - - aunque todo esto está compilado en el mismo "programa" compilado, y el RTOS no es más que una biblioteca que ha incluido. Los más grandes comienzan a almacenar partes del código en lugares separados, y creo que algunos de ellos incluso pueden cargar trozos de código de los discos, al igual que Windows y Linux cuando ejecutan un programa. Es una especie de continuo, en lugar de uno u otro.
El sistema FreeRTOS es un RTOS de código abierto que se dirige hacia el extremo más pequeño del espacio RTOS; pueden ser un buen lugar para ver algo de esto si estás más interesado. Tienen algunos ejemplos de aplicaciones x86, que te darían una idea de qué tipo de sistemas x86 ejecutarían un programa baremo o basado en RTOS y cómo compilarías algo para ejecutar en uno; enlace aquí: http://www.freertos.org/a00090.html#186.
El compilador de Intel no es lo que usted piensa, es simplemente otro compilador de Windows (o Linux, ambos) que pasa a ser escrito por Intel. Hace EXEs o binarios estándar de Linux. –