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]