Este é um tópico importante e não posso dar uma resposta simples, mas ...
Você pode se aproximar um pouco mais dessa resposta dividindo e conquistando, e como a outra resposta tenta atacar esse problema do ponto de vista do hw, tentarei de um ponto de vista de alto nível do SW.
Se você escreve algum software no código digamos c (um nível muito alto de abstração), não vê realmente o que está acontecendo e não entende realmente todas as coisas que você está perguntando.
Mas vamos começar de qualquer maneira.
Um programa simples que apenas inclui uma variável.
int main(void)
{
int i=0;
while(1) {
i++;
}
}
Então precisamos pegar o código do assembler para entender o que está acontecendo. Esta etapa pode ser executada em qualquer plataforma que você usar, mas, para simplificar, eu uso o gcc em um PC (mas isso não importa ...)
gcc -O0 -S main.c -o main.lst
Então, acabamos com algo assim:
.file "main.c"
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
subl $16, %esp
movl $0, -4(%ebp)
.L2:
addl $1, -4(%ebp)
jmp .L2
.size main, .-main
.ident "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"
.section .note.GNU-stack,"",@progbits
Então você tenta entender todas as linhas de código e o que elas fazem.
E então você começa a analisar como todas as instruções são implementadas ... Por exemplo, o subl
subl $16, %esp
Neste ponto, é diferente em arquiteturas diferentes e x86, arm, pic é meio diferente ... Mas desde que meu exemplo foi x86.
E nesse nível, quando você ler a cópia, a maioria das ações parecerá que você está apenas movendo os números e, de certa forma, é isso que está acontecendo. Temos um programa predefinido em que pisamos, esse programa é armazenado em algum tipo de memória flash que geralmente é algum tipo de lógica eletrônica que interceptará um nível lógico.
Se você vê algum tipo de " flip-flop " para cada parte, então você está perto, e então precisamos de muitas delas. Aqui começamos a encontrar os seus e zeros.
Então, para que alguma ação ocorra, adicionamos uma lógica interessante que pode transformar um número em outro (a própria CPU).
E então seguimos o programa um passo de cada vez, e para saber onde estamos, temos um contador de programas (PC). E mova os números para trás e para a quarta e armazene aqueles em outra memória que também é uma espécie de grade com flip-flops.
Mas vamos voltar a um exemplo específico novamente, para entender um pouco melhor a CPU, podemos dar uma olhada na ALU e nesta imagem simplificada . Onde você pode ver que, quando movermos dados para esse bloco lógico e selecionarmos alguma operação com os pinos OP, obteremos um novo resultado na saída. Que nós, por sua vez, podemos voltar para algum lugar na memória.
E amaldiçoar sua ULA na parte da CPU da sua UCP é muito mais complexa que essa, mas opera com o mesmo princípio básico.
Nesse ponto, podemos ver algum circuito lógico que faz o "trabalho" de um lado e algum armazenamento do outro lado. E o armazenamento tem duas partes, uma para o programa e outra para os dados. Mas como nós realmente "nos movemos", então, esses devem estar conectados de alguma maneira ...
E é aqui que conectamos essas peças a um ônibus.
Um barramento é apenas alguns fios que conectam as diferentes partes e, em seguida, a lógica de controle informa à memória quais dados enviar para esse barramento e qual parte da CPU que deve escutar esses dados enviados. E isso é feito com algumas linhas de controle paralelas que habilitarão / desabilitarão as diferentes partes.
...
Portanto, se você escolher seu mcu de escolha e dissecar um programa muito pequeno, e contanto que não entenda o que está acontecendo, você o dissecará ainda mais até ter um belo quebra-cabeça que pode ser usado para criar um "mcu".
E não se esqueça de ler a folha de dados do seu mcu e verificar com que tipo de peças ele foi feito, como que tipo de memória, alu, ônibus etc.
Espero que isto ajude um pouco ???
Boa sorte