Vistas de página en total

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



No hay comentarios:

Publicar un comentario

Si tienes algún comentario, duda o sugerencia, o si quieres aportar algún código creado a partir de las librerías expuestas aquí, por favor, indícamelo.