Para implementar la tarea donde tuvimos que leer del usuario dos números enteros, realizar operaciones con ellos y desplegar el resultado, fue necesario implementar dos rutinas muy interesantes: itoa (para convertir un entero a cadena) y atoi (para convertir una cadena a entero). Los nombres de estas dos rutinas los tomé de las funciones en C que ayudan a realizar estás tareas, entero a cadena (integer to ascii por sus siglas en inglés) y cadena a entero (ascii to integer). En este post analizaremos la implementación de atoi.
El objetivo de esta función es tomar una cadena y convertirla a su valor entero. Por ejemplo la cadena “120” debe generar el entero 120. El pseudo-código para esta función es el siguiente:
1 entero = 0 2 temp = 0 3 indice = 0 4 while cadena[indice] es un digito 5 temp = convertir cadena[indice] a digito 6 entero = entero * 10 7 entero = entero + temp 8 indice = indice + 1 9 end while
Recuerden que en ascii los caracteres '0' al '9' se encuentran de manera consecutiva, de hecho el valor númerico de '0' es 30h y el de '9' es 39h. Por lo que el paso 4 del código anterior se puede implementar fácilmente verificando si cadena[indice] se encuentra entre '0' y '9'. De la misma forma, en el paso 5, sólo basta con restar el valor de '0' a cadena[indice] para obtener el valor del dígito en esa posición. El siguiente post muestra el código en ensamblador para esta función (sólo tuve que cambiar los registros de 32 a 16 bits, por ejemplo de eax a ax).
La siguiente función muestra la versión de 16 bits de atoi, la cadena a convertir debe iniciar en DS:SI y el valor final lo regresa en BX.
; ========= Convertir cadena a numero ===========
; Parametros
; si: offset inicial de la cadena con respecto a DS
; Retorna
; bx: valor
atoi proc
xor bx,bx ;BX = 0
atoi_1:
lodsb ;carga byte apuntado por SI en AL
;e incrementa si
cmp al,'0' ;es numero ascii? [0-9]
jb noascii ;no, salir
cmp al,'9'
ja noascii ;no, salir
sub al,30h ;ascii '0'=30h, ascii '1'=31h...etc.
cbw ;byte a word
push ax
mov ax,bx ;BX tendra el valor final
mov cx,10
mul cx ;AX=AX*10
mov bx,ax
pop ax
add bx,ax
jmp atoi_1 ;seguir mientras SI apunte a un numero ascii
noascii:
ret ;BX tiene el valor final
atoi endp
No hay comentarios:
Publicar un comentario