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