En el anterior articulo, vimos un par de warriors que se centraban en la evasión de los ataques,Imp,Trasgo,etc.. en este articulo nos meteremos mas en harina y veremos ejemplos de ataques.
Dwarf
;redcode
;name Dwarf
;author A. K. Dewdney
ADD #4, 3
MOV #2, @2
JMP -2
El ataque de el enano se basa en esparcir por el core, paquetes de datos en forma de bomba(en múltiplos de cuatro) para intentar alcanzar a nuestro oponente.
Como este código tiene algo mas de chicha, iremos por partes
-
La instrucción ADD: Esta instrucción se usa para sumar un origen y un destino y poner el resultado en el destino, en la primera linea lo que hacemos es sumar el numero 4 a la dirección 3 y poner en resultado en esta, para ello se usa el símbolo de direccionamiento inmediato #, que significa que estamos añadiendo DATOS.
-
La instrucción MOV:Esta instrucción se usar para mover datos de un origen a un destino, en este caso lo que hacemos es mover la instrucción 2 a la dirección que apunta su dirección B usando un direccionamiento indirecto @, no queremos que se copie sobre si mismo solo que haga referencia a su dirección. Las instrucciones en ASM tienen un campo A(origen) y un campo(B) destino,
-
La instrucción JMP: Esta instrucción realiza una salto incondicional, osea salta de dirección sin necesidad de condiciones, en este caso salta dos direcciones hacia atrás para empezar de nuevo el bucle.
En la web de –> http://vyznev.net/corewar/guide.html podemos ver un ejemplo que nos ayuda a entender esto de una forma mas gráfica.
ADD #4, 3
MOV 2, @2 ; --.
JMP -2 ; | +2
DAT #0, #4 ; <--' --. The B-field of the MOV points here.
... |
... | +4
... |
DAT #0, #4 ; <------' The B-field of the DAT points here.
Lo primero que tenemos que ver es que en redcode y ASM las instrucciones van en orden secuencial por lo que es importante entender el orden en el que se ejecutan, por ejemplo la instrucción ADD nos esta diciendo que va a añadir el numero 4(recordar que esta usando un direccionamiento directo) a la instrucción 3 que en ese caso es un DAT. Si vamos a la segunda instrucción el MOV nos esta indicando que se va a mover la dirección 2(el MOV) en a la dirección que apunta, por eso se usa @, puesto que si no indicamos que es un direccionamiento indirecto, se copiaría sobre si misma. Como se puede ver el campo B del DAT se incrementa en 4 cada vez y vuelve al inicio del bucle, gracias al JMP.
Nuestro enano, seguirá lanzando bombas cada cuatro instrucciones por todo el núcleo,hasta que de una vuelta completa(recordar que el núcleo es un anillo), esta instrucción no funcionaria si el tamaño del núcleo no fuera divisible por cuatro, puesto que entonces nos podríamos disparar a nosotros mismos.
En el anterior articulo fijábamos el tamaño del core en 8000 con assert CORESIZE en este caso haremos lo mismo para asegurarnos que el tamaño del núcleo en compatible con nuestro ataque.
Vamos a usar una variante al código de Dewdney para nuestro enano que podemos encontrar en nuestro directorio warriors de pmars, añadiendo el DAT para, clarificar mejor el código aunque realmente no es necesario.
;name dwarf
;assert CORESIZE==8000
ADD #4, 3
MOV #2, @2
JMP -2
DAT #0, #0
A la arena
Al turrón, vamos a coger el código de nuestro trasgo el del primer articulo y enfrentarlo con nuestro enano a ver que pasa ;)
Es importante que pongamos un buen numero de rondas, puesto que si ponemos pocas rondas, las posibilidades que empaten son muchas, por ello usamos el siguiente comando(podemos usar el dwarf que tenemos en la carpeta warriors, o el que pusimos con el DAT es indiferente):
./pmars -r 8 ../warriors/imp.red ../warriors/dwarf.red
Como podemos ver nuestro enano, gana en la mayoría de rondas :)
De momento eso es todo, en los próximos artículos entraremos en mas detalle con el modo DEBUG para poder ver las instrucciones que se va ejecutando en memoria y veremos mas tipos de warriors.