Únete
a la comunidad
Inscríbete
Haz una pregunta »

Ejercicio de ensamblador x86: ocurrencia de un carácter

Mayo 2013




Introducción


Este pequeño ejercicio de ensamblador es para las arquitecturas x86 (procesador Intel y Amd 32 bits) y utiliza la sintaxis de Nasm, un ensamblador libre, gratuito y que puede ser utilizado en diferentes plataformas como Windows y Linux.
Las funciones externas utilizadas son sacadas de la biblioteca C estándar.

De este modo no tendrás problemas ligados a la maquina que utilizas para hacer este ejercicio: no depende del sistema operativo utilizado. Únicamente depende de la arquitectura x86.

Nota: Para utilizar nasm a fin de testear este ejercicio, haz clic aquí para ver un tutorial de uso/instalación de nasm para Windows y Linux.

Nociones abordadas en este ejercicio

  • Escritura de una función con gestión de parámetros de entrada
  • Gestión de matrices

Enunciado


Supongamos que tenemos una matriz de caracteres (que no termina necesariamente en 0). Sabemos su tamaño y desearíamos poder comprobar la presencia de un carácter determinado en esta matriz. Por lo tanto, el objetivo será crear una función que tome como entrada una matriz de caracteres, su tamaño y un carácter. Si este carácter está presente en la matriz, la función devolverá un valor diferente de cero, si no devuelve cero.

Esta seria la función en C:
//El modelo de esta función
int esta_en_la_matriz (char *matriz, int tamaño, char c);
//Ejemplo de uso:
char tab[] = {'n', 'e', 'u', 'e'};
esta_en_la_matriz (tab, sizeof(tab), 'u'); //Devolverá algo diferente a 0
esta_en_la_matriz (tab, sizeof(tab), 'a'); // Devolverá 0

Será necesario insertar este código dentro:
<code>extern printf

seccion .data
	matriz db 'dadedidadedavivoufufifamasibifisaz'
	si db 'si', 10, 0
	no db 'no', 10, 0

seccion .text
	global main

esta_en_la_matriz:
	;Inserte el código aquí!!


main:
	push ebp
	mov ebp, esp
	
       ;Vamos a verificar que m esté presente en la matriz
	push dword 'm'
	;La longitud de la matriz (aquí 34) 
	push dword 34 
	;Dirección de cadena en eax
	push matriz

        ;Llamado de esta_en_la_matriz con la dirección de la matriz, 
        ;su tamaño, y el valor a buscar
	call esta_en_la_matriz
	test eax, eax
	jnz esta_dentro;Si eax != 0 entonces mostrar sí
	push no ;Si no mostrar no
	jmp mostrar
        ;Mostrar la cadena con printf
   esta_dentro:
	push si
   mostrar:
	call printf

	mov eax, 0
	leave
	ret


Listo! Piensa unos cuantos minutos si es necesario. Haz una búsqueda sobre las instrucciones en relación a las cadenas.

Solución


Aquí una solución:
esta_en_la_matriz:
	;Obtenemos la dirección de la matriz (primer parámetro) de edi
	mov edi, [esp + 4] 
	;Obtenemos el tamaño de la matriz (segundo parámetro) de ecx
	mov ecx, [esp + 8]
	;Obtenemos el carácter a encontrar (tercer parámetro) de eax
	mov eax, [esp + 12]

	;Búsqueda del carácter
	repne scasb
	;Si el flag ZERO (ZF) esta en 1 es que se ha encontrado el carácter
	;Si no es que no se ha encontrado
	;Por lo tanto basta con poner el valor ZF en eax
	mov eax, 0
	;Si ZF = 1 entonces al = 1 (al siendo los 8 bits de menor peso de eax)
	setz al

	ret

Explicación


El objetivo era de utilizar la combinación de instrucciones de tipo “rep” y “scas”. Aquí hemos utilizado “repne”. Esta instrucción repite la instrucción que le sigue disminuyendo ecx en cada iteración. Este bucle se detiene cuando ecx=0 o cuando el Flag Zero (ZF) es 1. En cuanto a la instrucción scasb, busca la presencia de un carácter (almacenado en al, parte baja de eax) en el espacio de memoria señalado por edi. Si al es igual al valor señalado por edi, entonces el Flag Zero se pone en 1. Luego en todos los casos, edi es aumentado en 1.
Aquí vemos lo que pasa:
ZF = 0
ecx = longitud
eax = carácter
edi = matriz
//Bucle que representa "repne scasb"
Mientras ecx != 0 ET ZF = 0 Hacer
    Si al == [edi] Entonces
        ZF = 1
    FinSi
    ecx = ecx - 1
    edi = edi + 1
FinMientras

eax = 0
//Condición que representa el "setz"
Si ZF = 1 Entonces
    eax = 1
FinSi


Y listo!

Véase también

Comunidad de asistencia y consejos.

Exercice assembleur x86 occurence d'un caractère
Exercice assembleur x86 occurence d'un caractère
Por kilian el 10 de abril de 2008
Exercício do Assembly x86 ocorrência de um caractere
El artículo original fue escrito por kilian. Traducido por Carlos-vialfa.
Este documento intitulado « Ejercicio de ensamblador x86: ocurrencia de un carácter » de Kioskea (es.kioskea.net) esta puesto a diposición bajo la licencia Creative Commons. Puede copiar, modificar bajo las condiciones puestas por la licencia, siempre que esta nota sea visible.
Recibe nuestro newsletter

salud.kioskea.net

Ejercicio de ensamblador x86: número primo
Ejercicio de ensamblador para x86: invertir cadenas