Está en la página 1de 18

Programación Ensamblador

y lenguaje C
El ISA del AVR
Preliminares…

Preliminares
……
• 32 registros de 8 bits: R0 a R31
• Los registros pueden ser usados por su nombre genérico (Rx) o
renombrados mediante una directiva .def

.def registroTemporal = r16

• Las instrucciones son –en general- de 16 bits, con cero, uno o dos
operandos
• para instrucciones diádicas, el resultado es el primer operando

Add r5, r4 ; r5 = r5 + r4

• en las instrucciones con operandos inmediatos el destino sólo puede


ser un registro del segundo grupo (r16..r31)

Addi r5, 4 ; INVALIDO!!!


INVALIDO!!!

Addi r20, 4 ; VALIDO!!!


VALIDO!!!
El ISA del AVR
• Los pares de registros r26:r27, r28:r29 y r30:r31 actúan como los
registros de 16 bits X, Y y Z respectivamente.
• X, Y y Z se usan para acceder a la SRAM y Z para acceso a la memoria
de programa
• Las partes alta y baja de los registros indice (X, Y y Z) se acceden como
XH, XL; YH, YL y ZH, ZL respectivamente.
• Los puertos (A, B, C y D) tienen siempre una dirección fija independien-
temente del modelo de procesador.
• La SRAM no se accede directamente por al ALU de la CPU.
• El acceso a la SRAM se realiza a través de dos instrucciones específicas:
STS y LDS.
STS 0x0060, r1 ; M[0x0060] = r1
LDS r1, 0x0060 ; r1 = M[0x0060]

• El AVR soporta pila de hardware apuntada por un registro de 16 bits


SPH:SPL.
El ISA del AVR
• La pila crece hacia zonas bajas de memoria.
• La variable (de ensamblador) RAMEND aporta el valor de la dirección
mas alta de la memoria SRAM (la cual debe ser cargada en el SP)

Ldi r16, HIGH(RAMEND)


Out SPH, r16
Ldi r16, LOW(RAMEND)
Out SPL, r16

• Las instrucciones PUSH y POP escriben y leen directamente de la pila


El ISA del AVR
Diseño optimizado para ejecución eficiente de código C.
Las estructuras mas frecuentes de C se ensamblan en pocas (1, 2 ó 3)
instrucciones del procesador.

Aritméticas y lógicas

Salto

Grupos de Transferencia de datos


instrucciones
Bit y bit-test

Control de CPU
Instrucciones aritmético-lógicas
Add rd, rs ; rd = rd + rs

Adiw rdl, W ; rdh:rdl = rdh:rdl + W

Inc rd ; rd = rd + 1

Mul rd, rs ; R1:R0 = rd * rs

Fmul rd, rs ; R1:R0 = (rd * rs) << 1

Mulsu rd, rs ; R1:R0 = rd * rs

Tst rd ; rd = rd • rd

…..
Instrucciones de salto
Rjmp k ; PC = PC + k + 1

Ijmp ; PC = PC + Z

Jmp k ; PC = k

Cpse rd, rs ; if (rd==rs) PC = PC + (2 else 3)

Sbrc rs, b ; if (rs(b)==0) PC = PC + (2 else 3)

Sbrs rs, b ; if (rs(b)==1) PC = PC + (2 else 3)

Breq k ; if (Z==1) PC = PC + k + 1

Call k ; push PC , PC = k

Ret ; pop PC
Instrucciones de transferencia
de datos
Mov rd, rs ; rd = rs
Movw rd, rs ; rd+1:rd = rs+1:rs
Ldi rd, k ; rd = k
Ld rd, X ; rd = (X) ; St X, rs
Ld rd, X+ ; rd = (X) , X = X + 1 ; St X+, rs
Ld rd, -X ; X = X – 1 , rd = (X) ; St -X, rs
Ldd rd, Y+q ; rd = (Y+q) ; Std Y+q, rs
Lds rd, k ; rd = (k) ; Sts k, rs
Lpm ; R0 = (Z)
Lpm rd, Z ; rd = (Z)
Spm ; (Z) = R1:R0
Spm k, rs ; (Z) = rs+1:rs
In rd, P ; rd = P ; Out P, rs
Tratamiento de bits
Sbi P, b ; IO(P,b) = 1 ; Cbi P, b

Bset s ; SREG(s) = 1 ; Bclr s

Bst rd, b ; T = rd(b) ; Bld rd, s

Sec ;C=1 ; Clc

Sei ;I=1 ; Cli

Lsl rd ; rd(n+1) = rd(n) , rd(0) = 0

Clt ;T=0 ; Set

….
Control del procesador
Nop ; no operation

Sleep ; sleep processor

Wdr ; watch dog reset


Estructura de un programa en
ensamblador
Posee los siguientes elementos:

• Archivos a incluir (.include)

.include "8515def.inc“ ; Incluye el archivo completo en


.include “Uart.asm” este punto del archivo actual

• Reserva de espacio de memoria (.DB)

.DB 123,56,34,1 ; lista de 4 bytes


.DB “Esto es un texto” ; lista de bytes, cadena de caracteres.
.DW 13454 ; una palabra

• Definición de símbolos (.def)

.def registroTemporal=r16
ldi registroTemporal, 150
Estructura de un programa en
ensamblador
• Definición de constantes (.EQU)

.EQU bitCambiado = 5
sbi PortB, bitCambiado
cbi PortB, bitCambiado

• Modificación de dirección por defecto (.org)

.org 0x0000
rjmp reset
.org 0x0016
ldi r1, 54
.org 0x0010
.DB 1,2,3,4,5,6
Estructura de un programa en
ensamblador
• Inicio de código ejecutable (.CODE)

• Asignación a memoria SRAM (.DSEG)

• Definición de sección de eeprom (.ESEG)

• Definición de macros (.MACRO)

.MACRO Delay
nop
nop
nop
.ENDMACRO
Programando en C…
Hints importantes en un código C:

• Archivos include importantes:

#include <avr/io.h> ; Definiciones de IO específicas para el


dispositivo en uso

El archivo incluye:

• avr\common.h ; descripción de registros comunes a


todos los AVR
• avr\sfr_defs.h ; definición de registros especiales
• avr\portpins.h
• avr\version.h
Programando en C…
Hints importantes en un código C:

• La rutina principal y
al iz o nes
i io
inic rupc
Acá inter
//Función principal
ct i vo
int main(void) a
{
//Declaración e inicializaciones
eal iz a g
se r o lin
ito ce p o
fin
//Ciclo infinito l o in se ha s
while(1){ e l cic a y/ o ositivo
En ram d isp
//Código del programa prinicpal o g s
} el p
r a lo
}

NOTAR QUE: Un programa C siempre arranca ejecutando la rutina main


Un programa en assembler siempre arranca ejecutando
la interrupción 0 [Reset]
Programando en C…
La rutina principal .include "m8def.inc"

.org 0x0000
#include <avr\io.h>
rjmp RESET ;Reset Handle
#include <util\delay.h>
.def Temp1 = r16
int main(void) {
.def Temp2 = r17
//Puerto D como salida
.def Temp3 = r18
DDRD = 0xFF;
.def Step = r20
while (1){
; genera un delay de 256*256 unidades de tiempo
_delay_ms(150);
Delay:
Loop1: ldi Temp2,0
portD(0xE4);
Loop2: inc Temp2
portD(0xE8);
breq Loop1End
portD(0xD8);
rjmp Loop2
portD(0xD4);
Loop1End: inc Temp1
breq Loop1End
}
rjmp Loop1
}
Loop1End: ret
RESET: ldi Temp1, low(RAMEND)
out SPL, Temp1
ldi Temp1, high(RAMEND)
out SPH, Temp1
ldi Temp1, 0xff
out DDRD, Temp1
ldi Temp1, 0
Loop0: ldi Temp3, 55
Programando en C…
Las interrupciones…

#include <avr/io.h>
#include <avr/interrupt.h>

unsigned int incomingByte = 0x00;

#define CALC_BAUDRATE(baudrate) F_CPU/16/((baudrate)-1)


#define USART_BAUDRATE 51

void USART_Init(){
//Set baud rate
UBRRL=(unsigned char)USART_BAUDRATE; //low byte
UBRRH=(unsigned char)(USART_BAUDRATE>>8); //high byte
//Data format: asynchronous,no parity, 1 stop bit, 8 bit size
UCSRC=(1<<URSEL)|(0<<UMSEL)|(0<<UPM1)|(0<<UPM0)|(0<<USBS)|(0<<UCSZ2)
|(1<<UCSZ1)|(1<<UCSZ0);
//Enable Receiver and Interrupt on receive complete
UCSRB=(1<<RXEN)|(1<<RXCIE);
}
Programando en C…
Las interrupciones…

void USART_Tx( unsigned int data ){


/* Wait for empty transmit buffer */
while ( !( UCSRA & (1<<UDRE)) ){}
/* Put data into buffer, sends the data */
UDR = data;
}

ISR(USART_RXC_vect) {
incomingByte = UDR;
}

int main(void){

USART_Init();
ENABLE_IRQ;
USART_Tx('O');
USART_Tx('K');
USART_Tx(':');

for(;;){}
}

También podría gustarte