Vistas de página en total

Mostrando entradas con la etiqueta itoa. Mostrar todas las entradas
Mostrando entradas con la etiqueta itoa. Mostrar todas las entradas

viernes, 7 de marzo de 2014

ITOA

   Como un lector me planteó este problema, que ya tenía resuelto y me pasó su versión de la rutina para 32bits. He decidido volver a hacer una entrada con el proceso.
   Esta vez lo colocaré para TASM2.0, usando las directivas uses y argum. Aunque lo seguiré colocando en 16bits, ya que para 32 es idéntico. cambiando SI por ESI, DI por EDI etc y realizando la división en un solo paso (cambiando AX por EAX) , a no ser que se quiera hacer con números de 64 bits en cuyo caso la rutina quedaría igual que la actual, cambiando todos los registros a los extendidos.

En la versión puesta usámos procesador de 16 bits y interpretamos números de 32 bits:
        mov ax,[si+2]    ;toma la parte alta del número
       xor dx,dx             ;borra el resto
        div cx                ;divide por la base
        mov [si+2],ax         ; almacena el resultado
        mov ax,[si]        ;toma la parte baja
        div cx               ; divide por la base
        mov [si],ax          ;almacena el resultado
        mov bl,dl           ;toma el resto en bl, para indexar el caraceter


Si usásemos procesador de  32 bits y interpretamos números de 32 bits:
       mov ax,[esi]    ;toma la parte alta del número
       xor edx,edx             ;borra el resto
        div cx                ;divide por la base
        mov [esi],eax         ; almacena el resultado
         mov bl,dl           ;toma el resto en bl, para indexar el caraceter


Si usásemos procesador de  32 bits y interpretamos números de 64 bits:

        mov eax,[esi+4]    ;toma la parte alta del número
        xor dx,dx             ;borra el resto
        div cx                ;divide por la base
        mov [si+4]e,ax         ; almacena el resultado
        mov eax,[esi]        ;toma la parte baja
        div cx               ; divide por la base
        mov [esi],eax          ;almacena el resultado
        mov bl,dl           ;toma el resto en bl, para indexar el caraceter


El resto del paso a 32bits queda para el lector, ya que es muy sencillo.




ITOA.ASM
; Copyright (C) 2013  José Ángel Moneo Fernández

;    This program is free software: you can redistribute it and/or modify
;    it under the terms of the GNU General Public License as published by
;    the Free Software Foundation, either version 3 of the License, or
;   (at your option) any later version.

;    This program is distributed in the hope that it will be useful,
;    but WITHOUT ANY WARRANTY; without even the implied warranty of
;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;    GNU General Public License for more details.

;    You should have received a copy of the GNU General Public License
;    along with this program.  If not, see <http://www.gnu.org/licenses/>.

        public _itoa


.model compact,pascal

.data

caracteres db "0123456789ABCDEF"
numero dd 0
puntero dw 0
.code

proc _itoa uses bx cx dx si di,dest,dato,base
        mov cx,base       ;recogida del parámetro base a la que se convertirá
        mov bx,dato           ;recogida del parámetro numero de 16 bits a convertir
        mov si,offset numero   ;puntero a la variable auxiliar para procesamiento del número
        mov di,dest             ;recogida del parámetro destino, donde se quiere dejar el string de salida
        mov ax,[bx]              ;tomamos el numero a procesar y lo guardamos en la variable número
        mov [si],ax              ; primer word
        mov dx,[bx+2]              ;segundo word
        mov [si+2],dx
        cmp word ptr base,10       ;Verifica si la base es 10
        jne posit
        test word ptr [si+2],8000h   ; si la base es 10, verifica el signo en el bit alto
        jz posit
        xor word ptr [si],0ffffh     ; el signo es negativo y por lo tanto hace el complemento a 2
        xor word ptr [si+2],0ffffh
        add word ptr [si],1
        adc word ptr [si+2],0
        mov byte ptr [di],'-'          ; añade el signo a la cadena de salida
        inc di
        mov puntero,di               ; almacena el puntero para el inicio la posterior formación del número

  posit:
        xor bh,bh     ;inicia bh
        xor di,di    ;inica cuenta de caracteres , uso ahora di como contador
  conv:
        mov ax,[si+2]    ;toma la parte alta del número
        xor dx,dx             ;borra el resto
        div cx                ;divide por la base
        mov [si+2],ax         ; almacena el resultado
        mov ax,[si]        ;toma la parte baja
        div cx               ; divide por la base
        mov [si],ax          ;almacena el resultado
        mov bl,dl           ;toma el resto en bl, para indexar el caraceter
        mov dl,[bx+caracteres]   ; coge el caracter correspondiente al valor del resto
        push dx                 ;almacena en pila el caracter interpretado, para recogerlo luego en ax
        inc di                   ;incrementa di, usado como contador de caracteres
        cmp byte ptr [si],0        ;Ha terminado la conversión si el número ya es 0
        jne conv
        cmp byte ptr [si+2],0
        jne conv
        mov cx,di                ;almacena el contador en cx para la copia
        mov di,puntero           ; recupero el valor de DI como puntero al destino
   final:
        pop ax                     ; recupera el caracter interpretado
        mov [di],al                 ;almacena el caracter en la cadena
        inc di                       ;incrementa el puntero
        loop final                   ; continua la copia
        mov byte ptr [di],0           ; coloca el 0 de final de cadena
        ret
_itoa endp

end



domingo, 16 de junio de 2013

ENTERO A CADENA

    Esta es la función contraria a la anterior. A esta función le daremos un valor numérico (32bits) y nos devolverá una cadena alfanumérica que representa el número en la base indicada. El formato de la función, como en el resto de mis funciones queda reflejado en la llamada a la función rutina
   
ITOA.ASM
; Copyright (C) 2013  José Ángel Moneo Fernández

;    This program is free software: you can redistribute it and/or modify
;    it under the terms of the GNU General Public License as published by
;    the Free Software Foundation, either version 3 of the License, or
;   (at your option) any later version.

;    This program is distributed in the hope that it will be useful,
;    but WITHOUT ANY WARRANTY; without even the implied warranty of
;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;    GNU General Public License for more details.

;    You should have received a copy of the GNU General Public License
;    along with this program.  If not, see <http://www.gnu.org/licenses/>.

include main.mac
;_modelo com ; quitar el ; para  compilar para com

_code

rutina _itoa dest,dato,base
        push bx
        push cx
        push dx
        push si
        push di
        mov cx,[bp].base    ;recogida del parámetro base a la que se convertirá
        mov bx,[bp].dato   ;recogida del parámetro numero de 16 bits a convertir
        mov si,offset numero  ;puntero a la variable auxiliar para procesamiento del número
        mov di,[bp].dest     ;recogida del parámetro destino, donde se quiere dejar el string de salida
        mov ax,[bx]        ;tomamos el numero a procesar y lo guardamos en la variable número
        mov [si],ax        ; primer word
        mov dx,[bx+2]    ;segundo word
        mov [si+2],dx   
        cmp word ptr [bp].base,10   ;Verifica si la base es 10
        jne posit
        test word ptr [si+2],8000h  ; si la base es 10, verifica el signo en el bit alto
        jz posit
        xor word ptr [si],0ffffh      ; el signo es negativo y por lo tanto hace el complemento a 2
        xor word ptr [si+2],0ffffh
        add word ptr [si],1
        adc word ptr [si+2],0
        mov byte ptr [di],'-'        ; añade el signo a la cadena de salida
        inc di                              ; incrementa el puntero de salida
        mov puntero,di               ; almacena el puntero para el inicio la posterior formación del número   posit:

        xor di,di                       ;inica cuenta de caracteres , uso ahora di como contador  

         xor bh,bh                    ;inicia bh
  conv:
        mov ax,[si+2]           ;toma la parte alta del número
        xor dx,dx                ;borra el resto
        div cx                       ;divide por la base
        mov [si+2],ax        ; almacena el resultado
        mov ax,[si]        ;toma la parte baja
        div cx                ; divide por la base
        mov [si],ax    ;almacena el resultado
        mov bl,dl               ;toma el resto en bl, para indexar el caraceter
        mov dl,[bx+caracteres]       ; coge el caracter correspondiente al valor del resto
        push dx                         ;almacena en pila el caracter interpretado, para recogerlo luego en ax
        inc di                         ;incrementa di, usado como contador de caracteres
        cmp byte ptr [si],0    ;Ha terminado la conversión si el número ya es 0
        jne conv
        cmp byte ptr [si+2],0
        jne conv
        mov cx,di               ;almacena el contador en cx para la copia
        mov di,puntero; recupero el valor de DI como puntero al destino
   final:
        pop ax                  ; recupera el caracter interpretado
        mov [di],al         ;almacena el caracter en la cadena
        inc di                  ;incrementa el puntero
        loop final           ; continua la copia
        mov byte ptr [di],0    ; coloca el 0 de final de cadena
        pop di
        pop si
        pop dx
        pop cx
        pop bx
        pop bp
        ret
_itoa endp
_data
caracteres db "0123456789ABCDEF"
numero dd 0
puntero dw 0
_end






lunes, 10 de junio de 2013

DECLARACIÓN FUNCIONES DE CADENA

        Vamos a ver y crear parte de la librería STRING, la cual servirá para el manejo de cadenas. Es importante hacer parte de esta librería enseguida pues en ella tenemos la función itoa y atoi, que vamos a necesitar en las funciones Scanf y Prinf de la librería básica STDIO.
     Por ello comenzaré con la  cabecera STRING.MAC y posteriormente las funciones atoi y itoa, para poder realizar una parte muy importante de la librería que necesitaremos posteriormente para la librerías STDIO.
    Con esta parte de String y la posterior STDIO, estaremos ya en condiciones de hacer nuestros primeros programas de entrada y salida de texto y valores por pantalla.
 
     Como veis, no hace falta decir mucho de las funciones, pues son estructuras iguales a las anteriores, para las llamadas a las funciones auxiliares. Los nombres son parecidos a los usados en C.
      Con estas funciones podremos manejar los textos que entremos por teclado y presentarlos de forma adecuada. Igualmente, cuando más tarde creemos la librería FILE y IO, podremos crear bases de datos con sus ALTAS-BAJAS-MODIFICACIONES.
       Como podemos crear la macro, pero no usarla, podremos hacer el fichero .MAC con todas las funciones, pero solo implementar en la librería itoa y atoi. Lo haremos así, dejando el resto para después de los primeros ejemplos.


STRING.MAC
; Copyright (C) 2013  José Ángel Moneo Fernández

;    This program is free software: you can redistribute it and/or modify
;    it under the terms of the GNU General Public License as published by
;    the Free Software Foundation, either version 3 of the License, or
;   (at your option) any later version.

;    This program is distributed in the hope that it will be useful,
;    but WITHOUT ANY WARRANTY; without even the implied warranty of
;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;    GNU General Public License for more details.

;    You should have received a copy of the GNU General Public License
;    along with this program.  If not, see <http://www.gnu.org/licenses/>.

;pasa el caracter al a mayusculas
; se le puede pasar o no parámetro.
; Si no se le pasa parámetro asume que se pasa a mayusculas al
upr macro letra 
local salir
ifnb <letra>
        mov al,letra

endif
        cmp  al,'a'
        jb salir
        cmp al,'z'
        ja salir
        sub al,'a'-'A'
salir:
ifnb <letra>
        mov letra,al

endif
        endm

;pasa la cadena a mayusculas
strupr macro direccion
ifndef _may
    extrn _may:near
endif
        lea ax,direccion
        push ax
        call _may
        pop ax
endm

;devuelve la longitud de la cadena
STRLEN MACRO CADENA
ifndef _strlen
    extrn _strlen:near
endif
       lea AX,CADENA
       PUSH AX
       CALL _STRLEN
       ADD SP,2
ENDM

;compara dos cadenas devuelve las banderas como en una comparacion normal
strcmp macro destino,fuente
ifndef _strcmp
    extrn _strcmp:near
endif
        lea ax,fuente
        push ax
        lea ax,destino
        push ax
        call _strcmp
        pop ax
        pop ax
 endm

strcpy macro destino,fuente
ifndef _strcpy
    extrn _strcpy:near
endif
        lea ax,fuente
        push ax
        lea ax,destino
        push ax
        call _strcpy
        pop ax
        pop ax
 endm

strcut macro destino,inic,fin,fuente
ifndef _strcut
     extrn _strcut:near
endif
        lea ax,fuente
        push ax
        mov ax,fin
        push ax
        mov ax,inic
        push ax
        lea ax,destino
        push ax
        call _strcut
        add sp,8
 endm

strcat macro destino,fuente1,fuente2
 ifndef _strcat
      extrn _strcat:near
 endif
        lea ax,fuente2
        push ax
        lea ax,fuente1
        push ax
        lea ax,destino
        push ax
        call _strcat
        add sp,6
  endm


atoi macro destino,texto,base
  ifndef _atoi
        extrn _atoi:near
  endif
  ifb <base>
        mov ax,10
  else
        mov ax,base
  endif
        push ax
        lea ax,texto
        push ax
        lea ax,destino
        push ax
        call _atoi
        add sp,6
   endm


itoa macro destino,numero,base
ifndef _itoa
        extrn _itoa:near
endif
ifb <base>
        mov ax,10
else
        mov ax,base
endif
        push ax
        lea ax,numero
        push ax
        lea ax,destino
        push ax
        call _itoa
        add sp,6
 endm