section .data ;Cambiar Nombre y Apellido por vuestros datos. developer db "_Cristina_ _Vinuesa_",0 ;Constante que también está definida en C. ARRAYDIM equ 5 section .text ;Variables definidas en Ensamblador. global developer ;Variables globales definidas en C. extern charac, row, col extern aSecret, aPlay, pos, state, tries, hX ;Subrutinas de ensamblador que se llaman desde C. global posCurBoardP1, updatePosP1, updateArrayP1, checkSecretP1 global checkPlayP1, printHitsP1, printSecretPlayP1, playP1 ;Funciones de C que es llaman desde ensamblador. extern clearScreen_C, gotoxyP1_C, printchP1_C, getchP1_C extern printBoardP1_C, printMessageP1_C ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ATENCIÓN: Recordad que en ensamblador las variables y los parámetros ;; de tipo 'char' se tienen que asignar a registros de tipo ;; BYTE (1 byte): al, ah, bl, bh, cl, ch, dl, dh, sil, dil, ..., r15b ;; las de tipo 'short' se tiene que assignar a registros de tipo ;; WORD (2 bytes): ax, bx, cx, dx, si, di, ...., r15w ;; las de tipo 'int' se tiene que assignar a registros de tipo ;; DWORD (4 bytes): eax, ebx, ecx, edx, esi, edi, ...., r15d ;; las de tipo 'long' se tiene que assignar a registros de tipo ;; QWORD (8 bytes): rax, rbx, rcx, rdx, rsi, rdi, ...., r15 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Les subrutinas en ensamblador se teneis que implementar son: ;; posCurBoardP1, updatePosP1, updateArrayP1, ;; checkSecretP1, printSecretPlayP1, checkPlayP1, printHitsP1. ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Esta subrutina se da hecha. NO LA PODÉIS MODIFICAR. ; Situar el cursor en una posición de la pantalla ; llamando a la función gotoxyP1_C. ; ; Variables globales utilizadas: ; (row) : Fila de la pantalla donde se situa el cursor. ; (col) : Columna de la pantalla donde se situa el cursor. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; gotoxyP1: push rbp mov rbp, rsp ;guardamos el estado de los registros del procesador porque ;las funciones de C no mantienen el estado de los registros. push rax push rbx push rcx push rdx push rsi push rdi push r8 push r9 push r10 push r11 push r12 push r13 push r14 push r15 call gotoxyP1_C pop r15 pop r14 pop r13 pop r12 pop r11 pop r10 pop r9 pop r8 pop rdi pop rsi pop rdx pop rcx pop rbx pop rax mov rsp, rbp pop rbp ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Esta subrutina se da hecha. NO LA PODÉIS MODIFICAR. ; Leer un carácter desde el teclado sin mostrarlo en la pantalla ; y almacenarlo en la variable (charac) llamando a la función printchP1_C. ; ; Variables globales utilizadas: ; (charac) : Carácter que leemos desde el teclado. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; printchP1: push rbp mov rbp, rsp ;guardamos el estado de los registros del procesador porque ;las funciones de C no mantienen el estado de los registros. push rax push rbx push rcx push rdx push rsi push rdi push r8 push r9 push r10 push r11 push r12 push r13 push r14 push r15 call printchP1_C pop r15 pop r14 pop r13 pop r12 pop r11 pop r10 pop r9 pop r8 pop rdi pop rsi pop rdx pop rcx pop rbx pop rax mov rsp, rbp pop rbp ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Esta subrutina se da hecha. NO LA PODÉIS MODIFICAR. ; Leer una tecla y guardar el carácter asociado en la variable (charac) ; sin mostrarlo en pantalla, llamando a la función getchP1_C. ; ; Variables globales utilizadas: ; (charac) : Carácter que queremos mostrar. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; getchP1: push rbp mov rbp, rsp ;guardamos el estado de los registros del procesador porque ;las funciones de C no mantienen el estado de los registros. push rax push rbx push rcx push rdx push rsi push rdi push r8 push r9 push r10 push r11 push r12 push r13 push r14 push r15 push rbp call getchP1_C pop rbp pop r15 pop r14 pop r13 pop r12 pop r11 pop r10 pop r9 pop r8 pop rdi pop rsi pop rdx pop rcx pop rbx pop rax mov rsp, rbp pop rbp ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Posiciona el cursor dentro del tablero según la posición del cursor ; (pos) de los intentos que quedan (tries). ; Si estamos entrando la combinación secreta (state==0) nos pondremos en ; la fila 3 (row=3), si estamos entrando una jugada (state!=0) la fila ; se calcula con la fórmula: (row=9+(ARRAYDIM-tries)*2). ; La columna es calcula con la fórmula (col= 8+(pos*2)). ; Para posicionar el cursor se llama a la subrutina gotoxyP1. ; ; Variables globales utilizadas: ; (state) : Estado del juego. ; (tries) : Intentos que quedan. ; (row) : Fila de la pantalla donde se situa el cursor. ; (col) : Columna de la pantalla donde se situa el cursor. ; (pos) : Posición donde está el cursor. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; posCurBoardP1: push rbp mov rbp, rsp push rax ;state; push rbx ;cálculos fila; push rcx ;cálculos columna; mov ax, WORD[state] pcb_if: ;if (state==0) { cmp ax, 0 ;state == 0; jne pcb_if_else mov ebx, 3 ;row = 3; jmp pcb_if_end pcb_if_else: ;row = 9+(ARRAYDIM-tries)*2; mov ebx, ARRAYDIM ;ARRAYDIM; sub ebx, DWORD[tries] ;-tries; imul ebx, 2 ;*2; add ebx, 9 ;9+; pcb_if_end: mov DWORD[row], ebx ;row; mov ecx, DWORD[pos] ;pos; shl ecx, 1 ;*2; add ecx, 8 ;8+; mov DWORD[col], ecx ;col = 8+(pos*2); call gotoxyP1 pop rcx pop rbx pop rax mov rsp, rbp pop rbp ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Si se ha leído (charac=='j') izquierda o (charac=='k') derecha ; actualizar la posición del cursor (posición dentro del array de la ; combinación) controlando que no salga de las posiciones del array ; [0..4] y actualizar el índice del array (pos +/-1) según corresponda. ; No se puede salir de la zona donde estamos escribiendo (5 posiciones). ; ; Variables globales utilizadas: ; (charac) : Carácter leído desde el teclado. ; (pos) : Posición donde está el cursor. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; updatePosP1: push rbp mov rbp, rsp push rcx ;charac; mov cl, BYTE[charac] up_if1: ;if ((charac=='j') && (pos>0)) { cmp cl, 'j' ;charac=='j'; jne up_if1_end cmp DWORD[pos], 0 ;pos>0; jle up_if1_end dec DWORD[pos] ;pos--; up_if1_end: up_if2: ;if ((charac=='k') && (pos<ARRAYDIM-1) { cmp cl, 'k' ;charac=='k'; jne up_if2_end cmp DWORD[pos], (ARRAYDIM-1) ;pos<ARRAYDIM-1; jge up_if2_end inc DWORD[pos] ;pos++; up_if2_end: pop rcx mov rsp, rbp pop rbp ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Guardar el valor del carácter leído ['0'-'9'] en un array y ; mostrarlo en pantalla. ; Obtenemos el valor (val) restando 48 (ASCII de '0') a (charac). ; Si (state==0) guardamos el valor (val) en la posición (pos) del array ; (aSecret) y cambiaremos el carácter leído por un '*' (charac='*') ; para que no se vea la combinación secreta que escribimos. ; Si (state!=0) guardamos el valor (val) en la posició (pos) del array ; (aPlay). ; Finalmente mostramos el carácter (charac) en pantalla en la posición ; donde está el cursor llamando a la función printchP1_C. ; ; Variables globales utilizadas: ; (charac) : Carácter a mostrar. ; (state) : Estado del juego. ; (aSecret) : Array con la combinación secreta. ; (aPlay) : Array con la jugada. ; (pos) : Posición del array donde guardamos el valor leído [0..4]. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; updateArrayP1: push rbp mov rbp, rsp push rax ;charac; push rbx ;pos; push rcx ;val; mov al, BYTE[charac] ;charac; sub eax, '0' ;-'0'; mov ecx, eax ;val = (int)(charac-'0'); mov ebx, DWORD[pos] ua_if: ;if (state==0) { cmp WORD[state], 0 ;state == 0; jne ua_if_else mov DWORD[aSecret+ebx], ecx ;aSecret[pos]=val; mov BYTE[charac], '*' ;charac = '*'; jmp ua_if_end ua_if_else: mov DWORD[aPlay+ebx], ecx ;aPlay[pos]=val; ua_if_end: call printchP1 pop rcx pop rbx pop rax mov rsp, rbp pop rbp ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Verificar que la combinación secreta (aSecret) no tenga el valor -3, ; (valor inicial), ni números repetidos. ; Para cada elemento del array (aSecret) mirar que no haya un -3 ; y que no esté repetido en el resto del array (de la posición ; siguiente a la actual hasta el final). Para indicar que la combinación ; secreta no es correcta ponemos (secretError=1). ; Si la combinación secreta es correcta, poner (state=1) y vamos ; a leer jugadas. ; Si la combinación secreta es incorrecta, poner (state=2) para ; volverla a pedir. ; ; Variables globales utilizadas: ; (aSecret) : Array con la combinación secreta. ; (state) : Estado del juego. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; checkSecretP1: push rbp mov rbp, rsp push rax ;i; push rbx ;aSecret[j]; push rcx ;secretError; push rdx ;j; mov ecx, 0 ;secretError = 0; mov eax, 0 ;i = 0; cs_for1: ;for (i=0;i<ARRAYDIM;i++) { cmp eax, ARRAYDIM ;i < ARRAYDIM jge cs_for1_end cs_if1: ;if (aSecret[i]==-3) { cmp DWORD[aSecret+eax], -3 ;aSecret[i] == -3; jne cs_if1_end mov ecx, 1 ;secretError = 1; cs_if1_end: mov edx, eax inc edx cs_for2: ;for (j=i+1;j<ARRAYDIM;j++) { cmp edx, ARRAYDIM ;j < ARRAYDIM; jge cs_for2_end cs_if2: ;if (aSecret[i]==aSecret[j]) { mov ebx, [aSecret+edx] ;aSecret[j]; cmp [aSecret+eax], ebx ;aSecret[i]==aSecret[j]; jne cs_if2_end mov ecx, 1 ;secretError = 1; cs_if2_end inc edx ;j++; jmp cs_for2 cs_for2_end: inc eax ;i++; jmp cs_for1 cs_for1_end: cs_if3: ;if (secretError==1) { cmp ecx, 1 jne cs_if_else mov WORD[state], 2 ;state=2; jmp cs_if3_end cs_if_else: mov WORD[state], 1 ;state=1; cs_if3_end: pop rcx pop rbx pop rax mov rsp, rbp pop rbp ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Mostrar una combinación del juego. ; Si (state!=1) mostrar la combinación secreta (aSecret) en la fila 3 (row=3), ; si no, mostrar la jugada (aPlay) en la fila (row = 9+(ARRAYDIM-tr)*2), ; a partir de la columna 8 (col=8). ; Para cada posición del array: ; Posicionar el cursor llamando a la subrutina gotoxyP1 ; Si (state!=1) coger valor de la combinación secreta (aSecret), ; si no, coger valor de la jugada (aPlay), ; sumar '0' al valor cogido de l'array para convertirlo a carácter y ; llamar a la subrutina printchP1 para mostrarlo. ; Incrementar la columna de 2 en 2. ; ; Variables globales utilizadas: ; (state) : Estado del juego. ; (row) : Fila de la pantalla donde se situa el cursor. ; (col) : Columna de la pantalla donde se situa el cursor. ; (tries) : Intentos que quedan. ; (aSecret) : Array con la combinación secreta. ; (aPlay) : Array con la jugada. ; (charac) : Carácter a mostrar. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; printSecretPlayP1: push rbp mov rbp, rsp push rax ;i; push rbx ;cálculos fila; push rcx ;state; push rdx ;aSecret[i]; push rsi ;aPlay[i]; mov eax, 0 ;i = 0; mov cx, WORD[state] psp_if1: ;if (state!=1) { cmp cx, 1 ;state != 1; je psp_if1_else mov ebx, 3 ;row = 3; jmp psp_if1_end psp_if1_else: ;row = 9+(ARRAYDIM-tries)*2; mov ebx, ARRAYDIM ;ARRAYDIM; sub ebx, DWORD[tries] ;-tries; imul ebx, 2 ;*2; add ebx, 9 ;9+; psp_if1_end: mov [row], ebx ;row; mov DWORD[col], 8 ;col = 8; psp_for: ;for (i=0; i<ARRAYDIM; i++) { cmp eax, ARRAYDIM ;i<ARRAYDIM; jge psp_for_end call gotoxyP1 psp_if2: ;if (state != 1) { cmp cx, 1 ;state != 1; je psp_if2_else mov edx, DWORD[aSecret+eax] add dl, '0' ;+'0'; mov BYTE[charac], dl jmp psp_if2_end psp_if2_else: ;charac = aPlay[i]+'0'; mov esi, DWORD[aPlay+eax] add sil, '0' ;+'0'; mov BYTE[charac], sil psp_if2_end: call printchP1 add DWORD[col], 2 ;col = col + 2; inc eax ;i++; jmp psp_for psp_for_end: pop rdx pop rcx pop rbx pop rax mov rsp, rbp pop rbp ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Cuenta los aciertos en el sitio de la jugada (aPlay) ; respecto de la combinación secreta (aSecret). ; Comparar cada elemento de la combinación secreta (aSecret) con ; el elemento que hay en la misma posición de la jugada (aPlay). ; Si un elemento de la combinación secreta (aSecret[i]) es igual ; al elemento de la misma posición de la jugada (aPlay[i]): será un ; acierto en el sitio 'X' y se tiene que incrementar los aciertos en el ; sitio (hX++). ; Si todas las posiciones de la combinación secreta (aSecret) y de la jugada ; (aPlay) son iguales (hX=ARRAYDIM) hemos ganado y se tiene que modificar ; el estado del juego para indicarlo (state=3). ; Mostrar los aciertos en el sitio en el tablero de juego llamando ; a la subrutina printHitsP1. ; ; Variables globales utilizadas: ; (aSecret) : Array con la combinación secreta. ; (aPlay) : Array con la jugada. ; (state) : Estado del juego. ; (tries) : Intentos que quedan. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; checkPlayP1: push rbp mov rbp, rsp push rax ;i; push rbx ;hX; push rcx ;aPlay[i] mov eax, 0 ;i = 0; mov bx, 0 ;hX = 0; cp_for: ;for (i=0;i<ARRAYDIM;i++) { cmp eax, ARRAYDIM ;i<ARRAYDIM; jge cp_for_end cp_if1: ;if (aSecret[i]==aPlay[i]) { mov ecx, DWORD[aPlay+eax] cmp DWORD[aSecret+eax], ecx ;aSecret[i]==aPlay[i]; jne cp_if1_end inc bx ;hX++; cp_if1_end: inc eax ;i++; jmp cp_for cp_for_end: cp_if2: ;if (hX==ARRAYDIM) { cmp bx, ARRAYDIM ;hX == ARRRAYDIM jne cp_if2_end mov WORD[state], 3 ;state = 3; cp_if2_end: call printHitsP1 pop rdx pop rcx pop rbx pop rax mov rsp, rbp pop rbp ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Mostrar los aciertos en el sitio. ; Situar el cursor en la fila (9+(ARRAYDIM-tries)*2) y la columna ; (col = 22) (parte derecha del tablero) para mostrar los aciertos. ; De muestran tantas 'X' como aciertos en el sitio haya (hX). ; Para mostrar los aciertos se tiene que llamar a la subrutina gotoxyP1 ; para posicionar el cursor y printchP1 para mostrar los caracteres. ; Cada vez que se muestra un acierto se tiene que incrementar en 2 la ; columna. ; NOTA: (hX tiene que ser siempre menor o igual a ARRAYDIM). ; ; Variables globales utilizadas: ; (row) : Fila de la pantalla donde posicionamos el cursor. ; (col) : Columna de la pantalla donde posicionamos el cursor. ; (tries) : Intentos que quedan. ; (charac) : Carácter a mostrar. ; (hX) : Aciertos en el sitio. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; printHitsP1: push rbp mov rbp, rsp push rax ;cálculos fila; push rbx ;i; mov bx, [hX] ;i=hX; mov eax, ARRAYDIM ;ARRAYDIM; sub eax, DWORD[tries] ;-tries; shl eax, 1 ;*2; add eax, 9 ;9+; mov [row], eax ;row = 9+(ARRAYDIM-tries)*2; mov DWORD[col], 22 ;col = 22; mov BYTE[charac], 'X' ;charac = 'X'; ph_for: ;for (i=hX;i>0;i++) { cmp bx, 0 ;i>0; jle ph_for_end call gotoxyP1_C call printchP1_C add DWORD[col], 2 ;col = col + 2; dec bx ;i--; jmp ph_for ph_for_end: pop rbx pop rax mov rsp, rbp pop rbp ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Aquesta subrutina es dóna feta. NO LA PODEU MODIFICAR. ; Mostrar un mensaje en la parte inferior derecha del tablero según el ; valor de la variable (state). ; (state) : 0: Estamos entrando la combinación secreta, ; 1: Estamos entrando la jugada. ; 2: La combinación secreta tiene los valores iniciales o valores repetidos. ; 3: Se ha ganado, jugada = combinación secreta. ; 4: Se han agotado las jugadas. ; 5: Se ha pulsado ESC para salir. ; Se espera que se pulse una tecla para continuar. ; Mostrar un mensaje debajo del tablero para indicarlo ; y al pulsar una tecla lo borra. ; ; Variables globales utilizadas: ; (row) : Fila de la pantalla donde se situa el cursor. ; (col) : Columna de la pantalla donde se situa el cursor. ; (state) : Estado del juego. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; printMessageP1: push rbp mov rbp, rsp ;guardem l'estat dels registres del processador perquè ;les funcions de C no mantenen l'estat dels registres. push rax push rbx push rcx push rdx push rsi push rdi push r8 push r9 push r10 push r11 push r12 push r13 push r14 push r15 push rbp call printMessageP1_C pop rbp pop r15 pop r14 pop r13 pop r12 pop r11 pop r10 pop r9 pop r8 pop rdi pop rsi pop rdx pop rcx pop rbx pop rax mov rsp, rbp pop rbp ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Aquesta subrutina es dóna feta. NO LA PODEU MODIFICAR. ; Subrutina principal del juego ; Leer la combinación secreta y verificar que sea correcta. ; A continuación se lee una jugada, compara la jugada con la ; combinación secreta para determinar si son iguales. ; Repetir el proceso mientras no se acierte la combinación secreta y ; mientras queden intentos. Si se pulsa la tecla 'ESC' durante la ; lectura de la combinación secreta o de una jugada salir. ; ; Pseudo código: ; El jugador dispone de 5 intentos para acertar la combinación secreta, ; el estado inicial del juego es 0 y el cursor ese pone en la posición 0. ; Mostrar el tablero de juego llamando la función printBoardP1_C. ; Mostrar un mensaje indicando que se tiene que entrar la combinación ; secreta llamando a la subrutina printMessageP1. ; Mientras (state==0) leer la combinación secreta o (state==2) leer ; la combinación secreta porque no era correcta: ; - Poner el estado inicial del juego a 0 (state=0). ; Mientras no se pulse (ESC) o (ENTER): ; - Posicionar el cursor en el tablero llamando a la subrutina posCurBoardP1. ; - Leer una tecla llamando a la subrutina getchP1. ; - Si se ha leído una 'j'(izquierda) o una 'k' (derecha) mover el ; cursor por las 5 posiciones de la combinación, actualizando ; el índice del array (pos +/-1) llamando a la subrutina updatePosP1. ; (no se puede salir de la zona donde estamos escribiendo (5 posiciones)) ; - Si se ha leído un carácter válido ['0'-'9'] lo guardamos en el array ; (aSecret), si (status==0) cambiaremos el carácter leído por un ; '*' para que no se vea la combinación secreta que escribimos y ; mostramos el carácter en pantalla en la posición donde está el ; cursor llamando a la función updateArrayP1_C. ; - Si se ha leído un ESC(27) poner (state=5) para salir. ; ; Si no se ha pulsado la tecla (ESC) (state!=5) llamar a la subrutina ; checkSecretP1 para verificar si la combinación secreta tiene un -3 ; o números repetidos y mostrar un mensaje llamando a la subrutina ; printMessageP1 indicando que ya se pueden entrar jugadas (state=1) ; si la combinación secreta es correcta o que la combinación secreta ; no es correcta (state=2). ; ; Mientras (state==1) estamos introduciendo jugadas: ; - Inicializar la posición del cursor a 0 (pos=0). ; - Mostrar los intentos que quedan (tries) para acertar la combinación ; secreta, situar el cursor a la fila 21, columna 5 llamando a la subrutina ; gotoxyP1 y mostrar el carácter asociado al valor de la variable ; (tries) sumando '0' y llamando a la subrutina printchP1. ; - Mostrar la jugada que tenemos en el array (aPlay), inicialmente ; será ("00000") y se podrá modificar. ; Mientras no se pulse (ESC) o (ENTER): ; - Posicionar el cursor en el tablero llamando a la subrutina posCurBoardP1. ; - Leer una tecla llamando a la subrutina getchP2. ; - Si se ha leído una 'j'(izquierda) o una 'k' (derecha) actualizar ; la posiciób del cursor, índice del array, (pos +/-1) llamando a ; la subrutina updatePosP1. ; (no se puede salir de la zona donde estamos escribiendo (5 posiciones)). ; - Si se ha leído un carácter válido ['0'-'9'] lo guardamos en el ; array (aPlay) y mostramos el carácter en pantalla en la posición ; donde está el cursor llamando a la funció updateArrayP1_C. ; - Si se ha leído un ESC(27) poner (state=5) para sortir. ; ; Si no se ha pulsado (ESC)(state!=5) llamar a la subrutina chekPlaysP1 ; para contar los aciertos en el lugar de la jugada (aPlay) ; respecto de la combinación secreta (aSecret), si la jugada es igual, ; posición a posición, en la combinación secreta, hemos ganado (state=3). ; Decrementamos los intentos (tries), y si no quedan intentos (tries==0) y ; no hemos acertado la combinación secreta (state==1), hemos perdido (state=4). ; ; Para acabar, mostrar la combinación secreta llamando a la subrutina ; printSecretPlayP1. Mostrar los intentos que quedan (tries) para ; acertar la combinación secreta, situar el cursor en la fila 21, ; columna 5 llamando a la subrutina gotoxyP1 y mostrar el carácter asociado ; al valor de la variable (tries) sumando '0' y llamando a la subrutina ; printchP1, finalmente mostrar el mensaje indicando cual ha sido ; el motivo llamando a la subrutina printMessageP1. ; Se acaba el juego. ; ; Variables globales utilizadas: ; (state) : Estado del juego. ; (tries) : Intentos que quedan. ; (pos) : Posición donde está el cursor. ; (charac) : Carácter leído desde el teclado y a mostrar. ; (row) : Fila de la pantalla donde se situa el cursor. ; (col) : Columna de la pantalla donde se situa el cursor. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; playP1: push rbp mov rbp, rsp push rcx mov WORD[state], 0 mov DWORD[tries], 5 mov DWORD[pos], 0 call printBoardP1_C ;printBoardP1_C(); call printMessageP1 ;printMessageP1_C(); P1_while1: cmp WORD[state], 0 ;while (state == 0 je P1_while1ok cmp WORD[state], 2 ;|| state==2) { jne P1_endwhile1 P1_while1ok: mov WORD[state], 0 ;state=0; P1_do1: ;do { call posCurBoardP1 ;posCurBoardP1_C(); call getchP1 ;charac = getchP1_C(); mov cl, BYTE[charac] cmp cl, 'j' ;if ((charac=='j') je P1_if11 cmp cl, 'k' ;|| (charac=='k')){ jne P1_endif11 P1_if11: call updatePosP1 ;pos = updatePosP1_C(); P1_endif11: ;} cmp cl, '0' ;if (charac>='0' jl P1_endif12 cmp cl, '9' ;&& charac<='9'){ jg P1_endif12 call updateArrayP1 ;updateArrayP1_C(); P1_endif12: ;} cmp cl, 27 ;if (charac== 27) { jne P1_endif13 mov WORD[state], 5 ;state = 5; P1_endif13: ;} cmp cl,10 ;} while ((c!=10) je P1_enddo1 cmp cl, 27 ;&& (charac!=27)); jne P1_do1 P1_enddo1: cmp WORD[state], 5 ;if (state!=5) { je P1_endif14 call checkSecretP1 ;checkSecretP1_C(); call printMessageP1 ;printMessageP1_C(); P1_endif14: ;} jmp P1_while1 P1_endwhile1: ;} P1_while2: ;while (state == 1) cmp WORD[state], 1 jne P1_endwhile2 mov DWORD[pos], 0 ;pos=0; mov DWORD[row], 21 mov DWORD[col], 5 call gotoxyP1 ;gotoxyP1_C(); mov edi, DWORD[tries] add dil, '0' mov BYTE[charac], dil ;charac=tries + '0'; call printchP1 ;printchP1_C(); call printSecretPlayP1 ;printSecretPlayP1_C(); P1_do2: ;do { call posCurBoardP1 ;posCurBoardP1_C(); call getchP1 ;getchP1_C(); mov cl, BYTE[charac] cmp cl, 'j' ;if ((charac=='j') je P1_if21 cmp cl, 'k' ;|| (charac=='k')){ jne P1_endif21 P1_if21: call updatePosP1 ;pos = updatePosP1_C(); P1_endif21: ;} cmp cl, '0' ;if (charac>='0' jl P1_endif22 cmp cl, '9' ;&& charac<='9'){ jg P1_endif22 call updateArrayP1 ;updateArrayP1_C(); P1_endif22: ;} cmp cl, 27 ;if (charac == 27) { jne P1_endif23 mov WORD[state], 5 ;state = 5; P1_endif23: ;} cmp cl,10 ;} while ((charac!=10) je P1_enddo2 cmp cl, 27 ;&& (charac!=27)); jne P1_do2 P1_enddo2: cmp WORD[state], 5 ;if (state!=5) { je P1_endif24 call checkPlayP1 ;checkPlayP1_C(); dec DWORD[tries] ;tries--; cmp DWORD[tries], 0 ;if (tries == 0 jne P1_endif25 cmp WORD[state], 1 ;&& state == 1) { jne P1_endif25 mov WORD[state], 4 ;state = 4; P1_endif25: ;} P1_endif24: ;} jmp P1_while2 P1_endwhile2: ;} mov DWORD[row], 21 mov DWORD[col], 5 call gotoxyP1 ;gotoxyP1_C(); mov edi, DWORD[tries] add dil, '0' mov BYTE[charac], dil ;charac=tries + '0'; call printchP1 ;printchP1_C(); call printSecretPlayP1 ;printSecretPlayP1_C(); call printMessageP1 ;printMessage_C(); P1_end: pop rcx mov rsp, rbp pop rbp ret
Write, Run & Share Assembly code online using OneCompiler's Assembly online compiler for free. It's one of the robust, feature-rich online compilers for Assembly language. Getting started with the OneCompiler's Assembly compiler is simple and pretty fast. The editor shows sample boilerplate code when you choose language as Assembly
and start coding.
Assembly language(asm) is a low-level programming language, where the language instructions will be more similar to machine code instructions.
Every assembler may have it's own assembly language designed for a specific computers or an operating system.
Assembly language requires less execution time and memory. It is more helful for direct hardware manipulation, real-time critical applications. It is used in device drivers, low-level embedded systems etc.
Assembly language usually consists of three sections,
Data section
To initialize variables and constants, buffer size these values doesn't change at runtime.
bss section
To declare variables
text section
_start
specifies the starting of this section where the actually code is written.
There are various define directives to allocate space for variables for both initialized and uninitialized data.
variable-name define-directive initial-value
Define Directive | Description | Allocated Space |
---|---|---|
DB | Define Byte | 1 byte |
DW | Define Word | 2 bytes |
DD | Define Doubleword | 4 bytes |
DQ | Define Quadword | 8 bytes |
DT | Define Ten Bytes | 10 bytes |
Define Directive | Description |
---|---|
RESB | Reserve a Byte |
RESW | Reserve a Word |
RESD | Reserve a Doubleword |
RESQ | Reserve a Quadword |
REST | Reserve a Ten Bytes |
Constants can be defined using
CONSTANT_NAME EQU regular-exp or value
%assign constant_name value
%define constant_name value
Loops are used to iterate a set of statements for a specific number of times.
mov ECX,n
L1:
;<loop body>
loop L1
where n specifies the no of times loops should iterate.
Procedure is a sub-routine which contains set of statements. Usually procedures are written when multiple calls are required to same set of statements which increases re-usuability and modularity.
procedure_name:
;procedure body
ret