Una vez entendiendo la función atoi del post anterior, decidí implementar la función que realiza la operación inversa. Ahora la entrada es un valor entero y lo debemos transformar en cadena. El pseudo-código se muestra a continuación:
1 temp = 0 2 indice = 0 3 while entero > 0 4 residuo = entero modulo 10 5 entero = entero div 10 6 cadena[indice] = residuo + 30h 7 indice = indice + 1 8 end while
La idea es ir extrayendo los dígitos (empezando por el menos significativo) e ir guardándolos en la cadena, noten que sumamos 30h para guardar el valor ascii que representa el dígito. Sin embargo, esta implementación genera una cadena al revés, es decir, si entero inicia con valor de 1234, la cadena final contendrá “4321”. Por lo que es necesario invertir esta cadena.
Pero es posible evitar invertir la cadena al final, para ello usaremos el stack (una estructura lifo – last in first out).
01 temp = 0 02 indice = 0 03 ndigitos = 0 04 while entero > 0 05 temp = entero modulo 10 06 entero = entero div 10 07 push temp 08 ndigitos = ndigitos + 1 09 end while 10 while ndigitos > 0 11 pop temp 12 cadena[indice] = temp + 30h 13 ndigitos = ndigitos – 1 14 indice = indice + 1 15 end while
El primer ciclo (línea 04-09) extrae los dígitos y los guarda en el stack, al final del ciclo el dígito más significativo se encuentran arriba del stack. El segundo ciclo (línea 10-15) extrae los dígitos del stack y los guarda en la cadena final.
El siguiente programa convierte dos cadenas a enteros usando atoi, los suma y convierte el resultado a cadena usando itoa para poder desplegarlo.
.model SMALL
.STACK 128
.DATA
cadena1 db '411$'
cadena2 db '144$'
cadena3 db 6 DUP(?)
op1 dw ?
op2 dw ?
.CODE
.STARTUP
mov ax,@data
mov ds,ax
main proc
; SI parametro
mov si, offset cadena1
call atoi
mov op1,bx
; SI parametro
mov si, offset cadena2
call atoi
mov op2,bx
; sumar
mov ax, op1
add ax, op2
mov bx, offset cadena3
call itoa
mov dx, offset cadena3
call desplegar
; INT 21h / AH=4Ch retorna el control al sistema operativo
; termina el programa
salir:
mov ax,4c00h
int 21h
ret
main endp
; ============ Proc: Desplegar mensaje ====================
; Parametros
; dx: offset de cadena terminada por $ con respecto a DS
desplegar proc
; INT 21h / AH=9 - despliega cadena apuntada por DS:DX.
; la cadena debe estar terminada por '$'.
mov ah,09h
;mov dx, offset cad
int 21h
ret
desplegar endp
; ========= 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
; =============== Convertir numero a cadena ===============
; Parametros
; ax: valor
; bx: donde guardar la cadena final
; Retorna
; cadena
itoa proc
xor cx,cx ;CX = 0
itoa_1:
cmp ax,0 ; El ciclo itoa_1 extrae los digitos del
je itoa_2 ; menos al mas significativo de AX y los
; guarda en el stack. Al finalizar el
xor dx,dx ; ciclo el digito mas significativo esta
push bx ; arriba del stack.
mov bx,10 ; CX contiene el numero de digitos
div bx
pop bx
push dx
inc cx
jmp itoa_1
itoa_2:
cmp cx,0 ; Esta seccion maneja el caso cuando
ja itoa_3 ; el numero a convertir (AX) es 0.
mov ax,'0' ; En este caso, el ciclo anterior
mov [bx],ax ; no guarda valores en el stack y
inc bx ; CX tiene el valor 0
jmp itoa_4
itoa_3:
pop ax ; Extraemos los numero del stack
add ax,30h ; lo pasamos a su valor ascii
mov [bx],ax ; lo guardamos en la cadena final
inc bx
loop itoa_3
itoa_4:
mov ax,'$' ; terminar cadena con '$' para
mov [bx],ax ; imprimirla con la INT21h/AH=9
ret
itoa endp
end

Excelente..!!! Gracias por compartirlo me fue de mucha ayuda.
ResponderEliminarQué bueno que te sirvió. Gracias por comentar :)!
Eliminar