lunes, 26 de marzo de 2012

Ensamblador 8086 atoi

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

lunes, 19 de marzo de 2012

Ensamblador 8086 en Ubuntu

En la clase de lenguaje ensamblador hemos estado usando un usb para iniciar en modo DOS y poder ejecutar nuestros programas de 16 bits. En este post, mostraré cómo realizar pruebas de nuestros programas en Ubuntu. Sin embargo, es importante probar nuestros programas al final en el modo DOS nativo en caso de que haya instrucciones no compatibles o que se comporten diferente.

  1. Instalar DOSBox que emula el ambiente DOS.
    sudo apt-get update
    sudo apt-get install dosbox
  2. Copiar los archivos de nuestro usb masm/bin en una carpeta, por ejemplo: /media/common/prgrmmng/8086. Para su conveniencia el siguiente zip contiene los archivos.
  3. Abrir DOSBox (Applications > Games > DOSBox Emulator), montar la carpeta del paso anterior en la unidad c, y cambiar a la unidad c.
  4. Ya estamos listos para empezar a programar. La siguiente imagen muestra la primer tarea corriendo en DOSBox.

El siguiente post también tiene información para bajar DOSBox para windows.

Si alguien usa DOSBox, por favor compartan si encuentran alguna incompatibilidad o problema con los programas.