Como alguém que escreveu programas executados sem um sistema operacional, ofereço uma resposta definitiva.
Um executável precisaria de um kernel do SO para ser executado?
Isso depende de como esse programa foi escrito e construído.
Você pode escrever um programa (supondo que tenha conhecimento) que não exija um sistema operacional.
Esse programa é descrito como autônomo .
Carregadores de inicialização e programas de diagnóstico são usos típicos para programas autônomos.
No entanto, o programa típico gravado e construído em algum ambiente do sistema operacional host será padronizado para execução no mesmo ambiente do sistema operacional host.
São necessárias decisões e ações muito explícitas para escrever e criar um programa independente.
... a saída do compilador é o código da máquina (executável) que eu pensei que eram instruções diretamente para a CPU.
Corrigir.
Recentemente, eu estava lendo sobre kernels e descobri que os programas não podem acessar o hardware diretamente, mas precisam passar pelo kernel.
Essa é uma restrição imposta por um modo de CPU que o sistema operacional usa para executar programas e facilitada por certas ferramentas de compilação, como compiladores e bibliotecas.
Não é uma limitação intrínseca a todos os programas já escritos.
Portanto, quando compilarmos um código-fonte simples, digamos com apenas uma função printf (), e a compilação produzir o código de máquina executável, cada instrução nesse código de máquina será executada diretamente da memória (assim que o código for carregado na memória pelo SO ) ou cada comando no código da máquina ainda precisará passar pelo SO (kernel) a ser executado?
Toda instrução é executada pela CPU.
Uma instrução que não é suportada ou é ilegal (por exemplo, o processo tem privilégios insuficientes) causará uma exceção imediata e a CPU executará uma rotina para lidar com essa condição incomum.
Uma função printf () não deve ser usada como um exemplo de "código fonte simples" .
A tradução de uma linguagem de programação de alto nível orientada a objetos para código de máquina pode não ser tão trivial quanto você sugere.
E então você escolhe uma das funções mais complexas de uma biblioteca de tempo de execução que realiza conversões de dados e E / S.
Observe que sua pergunta estipula um ambiente com um sistema operacional (e uma biblioteca de tempo de execução).
Depois que o sistema é inicializado e o sistema operacional recebe o controle do computador, são impostas restrições sobre o que um programa pode fazer (por exemplo, a E / S deve ser executada pelo sistema operacional).
Se você espera executar um programa independente (ou seja, sem um sistema operacional), não deve inicializar o computador para executar o sistema operacional.
... o que acontece depois que o código da máquina é carregado na memória?
Isso depende do meio ambiente.
Para um programa independente, ele pode ser executado, ou seja, o controle é entregue pulando para o endereço inicial do programa.
Para um programa carregado pelo sistema operacional, o programa precisa ser vinculado dinamicamente às bibliotecas compartilhadas das quais depende. O sistema operacional precisa criar um espaço de execução para o processo que executará o programa.
Ele passará pelo kernel ou conversará diretamente com o processador?
O código da máquina é executado pela CPU.
Eles não "passam pelo kernel" , mas nem "conversam com o processador" .
O código da máquina (que consiste em código operacional e operandos) é uma instrução para a CPU que é decodificada e a operação é executada.
Talvez o próximo tópico que você deva investigar seja o modo CPU .