No me queda claro si será mejor comprobar que (sum == 0) o contar directamente el número de rondas.
Ahi yo me cause una confusion tambien. Si se observa en C, sum es de 32 bits unsigned
Cuando se hace sum = XTEA_DELTA * num_round, se desplaza el dato a la derecha, 5 lugares para el caso de 32bits
Vos me diste este valor XTEA_DELTA 0x9E3779B9
Que si lo multiplico por 32 quedaria: 0x13C6EF3720, 1 byte mas. Pero luego cuando se guarda en sum, por ser de 32bits termino con
sum = 0xC6EF3720
Si resto continuamente ese valor siempre va a ser de 32bits, Por eso pienso que la condicion no debe ser sum = 0, lo pense en su momento para que contar las rondas si puedo esperar a 0, e incluso hice el ASM con sum de hasta 5 bytes. Pero luego me di cuenta que no es asi.
Tu ultimo codigo es justo, justo, identico, me copiaste, lo que estaba haciendo Picuino. xD
Loop_while
RCALL Termino
;Resta
SUB sum[0],XTEA_DELTA[0] ; sum -= XTEA_DELTA;
SBC sum[1],XTEA_DELTA[1]
SBC sum[2],XTEA_DELTA[2]
SBC sum[3],XTEA_DELTA[3]
;Cambio de lugar v0 y v1
MOVW Vtemp0[0],V1[0]
MOVW Vtemp0[2],V1[2]
MOVW V1[0],V0[0]
MOVW V1[2],V0[2]
MOVW V0[0],Vtemp0[0]
MOVW V0[2],Vtemp0[2]
RCALL Termino
;Cambio de lugar v0 y v1 , para la proxima ronda
MOVW Vtemp0[0],V1[0]
MOVW Vtemp0[2],V1[2]
MOVW V1[0],V0[0]
MOVW V1[2],V0[2]
MOVW V0[0],Vtemp0[0]
MOVW V0[2],Vtemp0[2]
DEC Count
BRNE Loop_while
RET
Termino
LDI ZL,0 ; Recargo valor de Z con el valor original, para la proxima obtencion de valores de llaves.
MOVW Vtemp0[0],V0[0] ; Vtemp0 para (v0<<4) y Vtemp1 para (V0 >> 5)
MOVW Vtemp0[2],V0[2]
MOVW Vtemp1[0],V0[0]
MOVW Vtemp1[2],V0[2]
LDI R0,4
RotateLeftv0 ; (v0 << 4)
LSL Vtemp0[0]
ROL Vtemp0[1]
ROL Vtemp0[2]
ROL Vtemp0[3] ; Por ser de 32 bits se deberian perder los bits que salgan de aca
DEC R0
BRNE RotateLeftv0
LDI R0,5
RotateRightv0 ; (V0 >> 5 )
LSR Vtemp1[3]
ROR Vtemp1[2]
ROR Vtemp1[1]
ROR Vtemp1[0]
DEC R0
BRNE RotateRightv0
EOR Vtemp0[0],Vtemp1[0] ; (v0 << 4) ^ (v0 >> 5)
EOR Vtemp0[1],Vtemp1[1]
EOR Vtemp0[2],Vtemp1[2]
EOR Vtemp0[3],Vtemp1[3]
ADD Vtemp0[0],V0[0] ; ((v0 << 4) ^ (v0 >> 5)) + v0
ADC Vtemp0[1],V0[1] ; Vtemp0 = ((v0 << 4) ^ (v0 >> 5)) + v0
ADC Vtemp0[2],V0[2]
ADC Vtemp0[3],V0[3]
SBRS Count,0
RJMP Primer_t ; Si es Par indica que es el primero. Si es impar es el segundo
;Seg_t
MOV R0,sum[0] ; sum & 3 , necesito multiplicarlo por 4, ya que son 4 bytes cada valor de llave
LSL R0
LSL R0
RJMP Save_Sum
Primer_t
MOV R0,sum[1] ; sum>>11 & 3 , 000a a000, 1 shift derecha, es igual a lo que se pide * 4
LSR R0
Save_Sum
ANDI R0,0x0C ; 0000 aa00
ADD ZL,R0 ; Le sumo el valor de R0 o lo que es igual a 4 * index
LD Vtemp1[0],Z+ ; key[sum&3] o key[(key>>11) & 3]
LD Vtemp1[1],Z+
LD Vtemp1[2],Z+
LD Vtemp1[3],Z+
ADD Vtemp1[0],sum[0] ; sum + key[(sum>>11) & 3]
ADC Vtemp1[1],sum[1] ; Aux = sum + key[(sum>>11) & 3]
ADC Vtemp1[2],sum[2]
ADC Vtemp1[3],sum[3]
EOR Vtemp0[0],Vtemp1[0] ; (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum>>11) & 3])
EOR Vtemp0[1],Vtemp1[1] ; Vtemp[0]
EOR Vtemp0[2],Vtemp1[2]
EOR Vtemp0[3],Vtemp1[3]
SUB V1[0],Vtemp0[0] ; v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum>>11) & 3])
SBC V1[1],Vtemp0[1]
SBC V1[2],Vtemp0[2]
SBC V1[3],Vtemp0[3] ; si ocurrio overflow ocurrio, lo lamento
RET
Me falta la parte de la inicializacion, en el que Z es a la base de Key
Paso de 105 lineas a 75, creo que podria reducirse en 3 lineas mas si hago el pasaje de V0 a V1 en un call.
R1 =
R2 =
R3 =
R4 =
R5 = Round
R6 = V1[0]
R7 = V1[1]
R8 = V1[2]
R9 = V1[3]
R10 = sum[0]
R11 = sum[1]
R12 = sum[2]
R13 = sum[3]
R14 = V0[0]
R15 = V0[1]
R16 = V0[2]
R17 = V0[3]
R18 = Vtemp0[0]
R19 = Vtemp0[1]
R20 = Vtemp0[2]
R21 = Vtemp0[3]
R22 = Vtemp1[0]
R23 = Vtemp1[1]
R24 = Vtemp1[2]
R25 = Vtemp1[3]
R26 = XL
R27 = XH
R28 = YL = SP
R29 = YH = SP
R30 = ZL
R31 = ZH
Como casi no utilizo la RAM podrias casi llenarla, esperar a decodificar todo y enviarle un mensaje al PC cuando este listo para recibir mas datos.
De la RAM necesito lugar para solo para los CALLs, cada CALL son 2bytes que es la direccion de retorno. Asi que para este codigo estara entre 3 a 4 CALLs como mucho. Inclusive el de llamada a desencriptarlo, unos 10bytes o por ahi cerca.
Hay 512 bytes. Asi que si haces bloques de 64bytes, podrias meter 7 bloques todo de una ocupandote 448 bytes y teniendo mucho espacio de RAM para el stack.
Si no era el problema el espacio, se podia pre-calcular sum, para cada vuelta. pero como el espacio apremia, entonces es preferible usar unas 10/20 instrucciones mas.
La otra es precalcularlo y guardarlo en una posicion especifica de la memoria, lo cual reduciria en 6 intrucciones el calculo de los terminos (lo cual haria mas rapido), pero agregaria mas instrucciones al inicio, por que hay que calcular todos los valores antes. Asi que estamos igual de mal sea la situacion que sea.
Mas compacto no se.. Intente usar las instrucciones que mejor se acomodaban para esto. Luego paso la inicializacion, Pero estoy mas que seguro que vas a terminar con unos 100 y algo de lineas.