Enviado por: rictad
« Online: Setembro 25, 2009, 11:12:54 pm »Não se preocupe com o modo Thumb-2. Verificando mais, acho que apenas o modo Thumb é usado nos firmwares. A instrução BL, no modo Thumb, tem realmente 32 bits, e não 16. Se tivesse apenas 16 bits, os saltos diretos seriam de no máximo 64 kbytes. Uma das vantagens do modo Thumb é tornar a execução mais rápida em memórias de 16 bits, e não limitar o tamanho da memória . Olhando na página 14 deste documento, percebi que a intrução BL possui sufixo de 16 bits e prefixo de 16 bits, totalizando 32 bits. Podemos ver isso no AASM com o seguinte exemplo:
E veremos que o BL para o endereço 0x000C terá 4 bytes (em tempo: sem o $, o AASM considera o endereço em decimal, ou seja, BL $000C é equivalente a BL 0012).
Mas é possível fazer a mudança entre os modos em tempo de execução. Acho que só algumas poucas rotinas dos firmwares Mediatek estão em modo ARM, incluindo o início do código. A mudança é feita por meio da instrução BX [Rm], em que Rm é qualquer um dos registradores, de R0 a R15 (lemprando que o R13 é usado como Stack Pointer, por isso também é chamado de SP, o R14 é usado como endereço de retorno de rotina, por isso muitas vezes é chamado de LR e o R15 é usado como contador de programa, daí também ser chamado de PC). O BX [Rm] fará um salto para o endereço que está armazenado em Rm, mas também trocará o modo de execução dependendo do bit 0 de Rm. Veja que uma rotina ARM ou Thumb sempre deve começar em um endereço par, o que facilita as coisas, pois as instruções ou são pares ou quádruplas de bytes. Se o bit menos significativo (bit 0) de Rm for 0, BX [Rm] fará um salto para o endereço em Rm sem mudar o modo de execução. Já se o bit menos significativo de Rm for 1 (endereço ímpar), BX [Rm] irá zerar o bit 0 de Rm (corrige o endereço para par), fará um salto para o endereço (corrigido) em Rm e irá mudar o modo de execução (de Thumb para ARM ou vice-versa). Dessa forma, é possível fazer rotinas em modo Thumb e outras em modo ARM.
Código: [Selecionar]
THUMB
INICIO ADD R0, R1, R1
ADD R2, R1, R1
LSL R1, R2, #3
BNE INICIO
BL $000C
E veremos que o BL para o endereço 0x000C terá 4 bytes (em tempo: sem o $, o AASM considera o endereço em decimal, ou seja, BL $000C é equivalente a BL 0012).
Mas é possível fazer a mudança entre os modos em tempo de execução. Acho que só algumas poucas rotinas dos firmwares Mediatek estão em modo ARM, incluindo o início do código. A mudança é feita por meio da instrução BX [Rm], em que Rm é qualquer um dos registradores, de R0 a R15 (lemprando que o R13 é usado como Stack Pointer, por isso também é chamado de SP, o R14 é usado como endereço de retorno de rotina, por isso muitas vezes é chamado de LR e o R15 é usado como contador de programa, daí também ser chamado de PC). O BX [Rm] fará um salto para o endereço que está armazenado em Rm, mas também trocará o modo de execução dependendo do bit 0 de Rm. Veja que uma rotina ARM ou Thumb sempre deve começar em um endereço par, o que facilita as coisas, pois as instruções ou são pares ou quádruplas de bytes. Se o bit menos significativo (bit 0) de Rm for 0, BX [Rm] fará um salto para o endereço em Rm sem mudar o modo de execução. Já se o bit menos significativo de Rm for 1 (endereço ímpar), BX [Rm] irá zerar o bit 0 de Rm (corrige o endereço para par), fará um salto para o endereço (corrigido) em Rm e irá mudar o modo de execução (de Thumb para ARM ou vice-versa). Dessa forma, é possível fazer rotinas em modo Thumb e outras em modo ARM.