O conjunto de instruções Thumb é um subconjunto de 16 bits do conjunto total de instruções de 32 bits da ARM. Cada instrução Thumb, além de trabalhar com o mesmo conjunto de registradores, possui uma correspondente de 32 bits que produz o mesmo efeito. Sendo de 16 bits, permite adensamento de código economizando espaço de memória flash e economia de energia, desejável em sistemas embarcados como, no caso, microcontroladores.
Sigamos então.
Estamos acostumados na programação de microcontroladores que, ao iniciar, a CPU executa a partir da posição zero de memória. No caso dos processadores ARM Cortex, o endereço zero de memória (mapeado na memória flash e remapeado no endereço 0x080000000 no processador STM32F051R8T6 presente na placa STM32F0Discovery) aponta para o chamado Vector Table que pode ser visto na figura abaixo:
Essa tabela começa, na posição 0x00000000, com o endereço inicial da pilha ou stack. Para esse processador, a pilha é descendente e o ponteiro para a pilha aponta para o último valor empilhado. Quando o processador é energizado, não há nada empilhado ainda, portanto a posição zero do Vector Table deve apontar para a última posição da memória RAM + 1. Novamente, no caso do processador STM32F051R8T6, que equipa a placa STM32F0Discovery, o endereço inicial da pilha deve ser 0x20002000. Quando for necessário guardar um valor na pilha, o processador subtrai 4 do ponteiro de pilha e armazena 4 bytes (ou 32 bits) na posição calculada. Na primeira vez que isso ocorrer, o processador obtém 0x20001ffc como novo ponteiro de pilha e armazena nas posições 0x20001ffc a 0x20001fff os 4 bytes.
Os processadores ARM Cortex podem organizar o acesso aos endereços na memória de duas formas: byte-invariant big-endian ou little-endian. Para o primeiro, os endereços são armazenados em registradores em ordem direta, do byte mais significativo ao menos significativo como na figura abaixo:
Byte-invariant big-endian |
Little-endian |
Onde o endereço 0x20002000 armazenado na posição de memória 0x00000000 (ou 0x08000000 remapeada) como valor inicial do ponteiro de pilha é, na verdade, armazenado na sequência 0x00, 0x20, 0x00, 0x20.
Seguindo com o Vector Table, a partir da primeira entrada (ponteiro inicial da pilha), ele possui uma entrada para o endereço inicial de execução de cada uma das funções de exceção do microcontrolador. Por se tratar de um processador de 32 bits, cada entrada tem essa dimensão. Para indicar que o código presente nas funções de exceção são de 16 bits (código Thumb) o bit menos significativo de cada vetor deve ser um.
A primeira função de exceção, ou a de número um, é a função de RESET a qual é acionada sempre que o microcontrolador é reiniciado. Na prática, este é o endereço da primeira instrução de usuário a ser executada quando o microcontrolador inicia. Novamente no exemplo acima, temos o endereço 0x08000008 como endereço da função de tratamento do RESET. Como o bit menos significativo está ligado (0x08000009) essa função possui código Thumb.
No próximo post, faremos nosso primeiro programa para a placa STM32F0Discovery.
REFERÊNCIAS
"Cortex-M0 Devices Generic User Guide", ARM
"The Definitive Guide to the ARM Cortex-M0",Joseph Yiu
"The Thumb instruction set"- http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0210c/CACBCAAE.html
"PM0215 - STM32F0xxx Cortex-M0 programming manual" - STMicroelectronics
Nenhum comentário:
Postar um comentário