EL68E – Sistemas Embarcados – Programação Assembly – Prof. Douglas Renaux
(Out/2014)
Os dois exercícios a seguir foram questões de prova em semestres anteriores.
1) Implemente em assembly (Cortex-M) a função:
int max_abs(int * vetor_valores, unsigned int size);
A implementação deve seguir rigorosamente a ATPCS.
A função max_abs recebe um vetor de valores por dois parâmetros: endereço
inicial do vetor e número de elementos no vetor. Deve identificar o elemento
com maior valor absoluto (ou seja, converter negativos para positivos ao
comparar). Para simplificar, considere que o valor 0x80000000 (maior valor
negativo que corresponde a -2.147.483.648) não está no vetor de entrada.
a) (0.5) usando o padrão ATPCS, qual(is) registrador(es) são usados para
passagem de parâmetros da função max_abs e qual(is) para o retorno ?
b) (2.5) escrever a função em assembly Cortex-M. Tamanho máximo do
código é de 20 instruções. Rotina mais longas serão desconsideradas.
Resposta na próxima página
código – preencha a tabela abaixo
label
instrução
operandos
comentários relevantes (*)
(*) – o comentário deve ser uma descrição do papel da instrução no código ao invés
de simplesmente informar o efeito sobre os registradores:
Exemplos:
1) Comentário NÃO relevante
MOV R0,#0 // o registrador R0 recebe o valor 0
2) Comentário relevante
MOV R0,#0 // inicializa o contador de repetições
2) ) Dado o seguinte problema:
Implementar uma rotina em assembly de Cortex-M3 que calcule y=f(x) usando
interpolação linear. A função f(x) é definida por alguns pares de pontos (Xi,Yi). Estes
pontos estão armazenados numa matriz de N linhas, tendo cada linha da matriz um
par de pontos, iniciando por (X0,Y0) e terminando por (XN-1,YN-1).
A assinatura da rotina que faz interpolação linear da função f é:
int li(int x_in, int N);
Ou seja, li recebe como parâmetros o valor de x (x_in) para o qual se deseja calcular
f(x_in) e o número de pontos (N) da função f(x) definidos na matriz coef.
Portanto, para calcular o valor de f(Xin) para um dado Xin no intervalo
X0 .. XN-1 a rotina deve identificar o intervalo onde Xin se encontra e fazer
interpolação linear naquele intervalo, conforme figura abaixo:
y = f(x)
Y3
Y2
Y=f(Xin)
f(Xin) = Y1 + (Xin-X1)*(Y2-Y1)/(X2-X1)
Y1
Y0
X0
X1
Xin
x
X2
X3
A matriz com os pontos da função f é uma
.
matriz Nx2, denominada coef, com valores inteiros.
.
Como por exemplo:
int coef[4][2] = {
.
{0, 2},
{15, 50},
X2 (em coef[2][0])
{30, 120},
{60, 210}};
Y1 (em coef[1][1])
O armazenamento desta matriz em memória é
X1 (em coef[1][0])
conforme apresentado na figura ao lado.
Y0 (em coef[0][1])
X0 (em coef[0][0])
.
.
.
0xFFFFFFFF
coef + 0xC
coef + 0x8
coef + 0x4
coef
0x0
0x0
Em resposta a este problema, um aluno escreveu o código em assembly apresentado a
seguir. Para este código:
a) complete o fluxograma (parcial) apresentado na figura a seguir, o fluxograma
deve representar a estrutura do código apresentado mas deve corrigir eventuais
erros deste código
b) apresente as correções que julgar necessárias no código apresentado.
a)
SECTION .text : CODE (2)
THUMB
PUBLIC li
li:
PUSH
{R4-R6}
LDR
R3,=coef
LDR
R4, [R3]
MOVS
R2, #1
CMP
R0, R4
BGE
L0
R3 := endereço inicial da
matriz com os pontos da
função a ser interpolada
i:= 1
ERRO:
MOV
R0, #-1
BX
LR
L2: ADDS
R2, R2, #1
L0: CMP
R2, R1
BGE
ERRO
LDR
R4, [R3, R2, LSL #3]
CMP
R0, R4
BHS
L2
ADD
R4, R3, R2, LSL #3
SUB
R1, R4, #8
LDR
R5, [R4, #-0x8]
LDR
R2, [R3, R2, LSL #3]
LDR
R6, [R1, #0x4]
LDR
R3, [R4, #-0x8]
SUBS
R0, R0, R5
LDR
R5, [R4, #0x4]
SUBS
R5, R5, R6
MULS
R0, R5, R0
SUBS
R2, R2, R3
SDIV
R0, R0, R2
POP
{R4-R6}
BX
LR
R4 := coef[i][0]
Download

(Out/2014) Os dois exercícios a seguir foram