• Jueves 14 de Noviembre de 2024, 16:54

Autor Tema:  Re: Novato pide ayuda con su primer procedimiento  (Leído 3263 veces)

colitroni

  • Nuevo Miembro
  • *
  • Mensajes: 8
    • Ver Perfil
Re: Novato pide ayuda con su primer procedimiento
« en: Jueves 9 de Octubre de 2003, 00:21 »
0
Bueno, esta es mi primera incursion en este lenguaje despues de leer y ver ejemplos. Lo que hago en el programa es leer un nº por teclado 2 bytes y lo que quiero es imprimirlo por pantalla y aqui es donde tengo el problema:

La tecnica que sigo es hallar el divisor (1,10,100,1000,10000) dependiendo de las cifras que tiene el nº introducido por el usuario; luego voy dividiendo el nº por el divisor, despues divido el divisor (para quitarle ceros) y ahi se produce un error de DIVIDE ERROR, el proc es el siguiente:

las definiciones que realizo son:

a dw ?        ;contiene el nº introducido

diez dw 10 ;cte de valor 10

PRINTNUM PROC NEAR
   mov dl,10   ; introduzco 1 retorno de carro
   mov ah,02
   int 21h
   mov dl,13   ; introduzco 1 retorno de carro
   mov ah,02
   int 21h
   mov ax,1   ; contador para saber el nº de cifras q tiene a
   mov bx,a   ; cargo en bx la variable a
   bucle:
   mul diez
   cmp ax,bx
   jbe bucle   ; multiplico ax por 10 hasta que ax>bx ojo el resultado es dx:ax
   div diez   ; asi tiene ax las mismas cifras q bx en este punto
   push ax   ; guardo el divisor
   SacaCifra:
   pop cx   ; meto el divisor en cx
   mov ax,bx   ; cargo en ax la variable cuyos digitos quiero mostrar
   div cx   ; y la divido por cx q será 1,10,100,1000 o 10000
   mov bx,dx   ; guardo el resto q es lo q queda por sacar
   mov dx,ax   ; ya que en ax está el cociente
   add dl,30h   ; así tengo el caracter ascii q coresponde al digito
   mov ah,02   ; lo saco en pantalla
   int 21h
   mov ax,cx   ; cargo el divisor en ax
   div diez   ; y le quito 1 cero ------------ ERROR QUE ME DA: DIVIDE ERROR ------------
   push ax   ; lo guardo en la pila
   cmp ax,1
   jae SacaCifra     
   ret
PRINTNUM   ENDP


Por cierto, al que quiera aprender como yo estoy haciendo, le recomiendo el emu8086 que es emulador, ensamblador y desensamblador todo en 1, funciona en Win9x,ME y XP y lo bueno es q si haces burradas, no se cuelga ya q es un emulador;) Si quisierais el nº de serie os podria pasar el mio para registrarlo;)

Salu2 y Espero vuestras respuestas

colitroni

  • Nuevo Miembro
  • *
  • Mensajes: 8
    • Ver Perfil
Re: Novato pide ayuda con su primer procedimiento
« Respuesta #1 en: Jueves 9 de Octubre de 2003, 02:43 »
0
Bueno, pues he encontrado el pequeño fallo. Era que como divido por word, no tenia en cuenta que dx no es cero llegado a esa linea, ya que en dl pongo el valor ascii del caracter para sacarlo por pantalla, asi pues me salia un nº enorme y claro al dividir por 10 me daba error de desbordamiento por división, la solucion la he encontrado leyendo en esta peich, por si os sirve de ayuda a los q como yo estamos empezando:

http://www.sinergia-web.com.mx/clases/a ... lase12.htm

Asi pues, funciona correctamente poniendo la ultima parte como queda:

   mov ax,cx   ; cargo el divisor en ax
   xor dx,dx   ; pongo a cero el word alto ya que el cociente es dx:ax
   div diez   ; y le quito 1 cero
   push ax   ; lo guardo en la pila
   cmp ax,1
   jae SacaCifra

Como veis he insertado un xor dx,dx para ponerlo a cero. Tambien hay que poner un pop ax justo antes del ret, o poner ret 2 para que desapile el ultimo push ax cuando ya no hay cifras que sacar.
Salu2.

Super_G

  • Miembro MUY activo
  • ***
  • Mensajes: 375
    • Ver Perfil
Re: Novato pide ayuda con su primer procedimiento
« Respuesta #2 en: Sábado 11 de Octubre de 2003, 14:39 »
0
El programa me parece interesante, pero tengo una duda: ¿el numero a mostrar de cuantos digitos es, ya que si es introducido(por teclado) estaria en ascii, y en que momento se introduce el numero?
eso seria todo Gracias

Super_G

  • Miembro MUY activo
  • ***
  • Mensajes: 375
    • Ver Perfil
Re: Novato pide ayuda con su primer procedimiento
« Respuesta #3 en: Sábado 11 de Octubre de 2003, 15:07 »
0
para mostrar un numero de 16bit que esta en AX:
;;*****************
         cmp ax,0  ;verifiacmos si AX es cero
         jz     fin     ;si lo es el programa termi
         mov si,offset cadena + 5;
         mov bx,10 ;dividor para obtener
c1:    xor  dx,dx  ;los digitos
         div bx        ;el digito va a DL
                          ;en AX el #restante
         add dl,48  ;lo convertimos en ascii
         mov [si],dl;movemos a la cadena
         dec si
         jmp c1 ;continuamos con el resto
fin:    mov ah,9
         mov dx,offset cadena
         int 21h
         int 20h
cadena db '00000$' ;cadena a ser mostradamostrada
;;****************        
no compile el programa pero espero que la idea se entienda

colitroni

  • Nuevo Miembro
  • *
  • Mensajes: 8
    • Ver Perfil
Re: Novato pide ayuda con su primer procedimiento
« Respuesta #4 en: Miércoles 15 de Octubre de 2003, 14:32 »
0
El usuario puede teclear un nº entre 0 y 65535 que es lo que corresponde a 2 bytes unsigned, ya que en el print_num no tengo encuenta el signo. La entrada termina cuando el usuario termina con enter. El nº queda almacenado en num y el procedimiento quedaria como sigue:

intronum proc near
   push ax
   push bx
   push dx
   lea bx,num   ; bx apunta a num
   xor dx,dx   ; pongo a cero dx
   mov [bx],dx
   introcar:
   mov ah,01h
   int 21h      ; espero caracter de usuario -> viene en al
   cmp al,13   ; si es enter....
   jz   fin      ; terminamos
   sub al,48   ; convierto el caracter a digito
   mov dl,al   ; guardo el digito en dx
   mov ax,[bx]   ; cargo en ax el valor momentaneo de la variable
   push dx   ; al multiplicar por word afecto a dx por eso lo guardo
   mul diez   ; lo multiplico por 10 ojo el resultado es dx:ax
   pop dx      ; recupero el valor de dx
   add ax,dx   ; le sumo el digito introducido para obtener el valor momentaneo
   mov [bx],ax   ; guardo el numero en la variable num
   jmp introcar:   ; voy a por el siguiente digito
   fin:
   pop dx
   pop bx
   pop ax
   ret
intronum endp

Ahora quiero tratar con nº mayores de 2 bytes (ya q estos caben en 1 reg y es facil la transferecia mem-reg-mem) Mi siguiente reto es intentar nº de 4 bytes con lo que ya podria almacenar nº bastante grandes. Mira a ver que te parecen las siguientes ideas:

1) Creo variable tipo dd (DoubleWord)
p.e.:      numero dd ?
2) Con LES ax,numero creo q tendria el word bajo en AX y el alto en ES, con lo que pasando ES a DX ya tendria mi nº en DX:AX dispuesto para realizar cualquier operacion aritmetica, esto correcto???
3) Tengo 1 duda q quiero preguntarte, una vez modificado ese nº DX:AX como lo paso otra vez a la variable numero, hay alguna instruccion de carga directa que me pudiera servir??? o podria hacerlo son SI apuntando a num y meter AX y luego incrementar SI en 2 y meter DX ???

Por cierto, en tu codigo al dividir, el resto no estaria en DX y el digito en al????

Espero tus respuestas, Salu2.

Super_G

  • Miembro MUY activo
  • ***
  • Mensajes: 375
    • Ver Perfil
Novato pide ayuda con su primer procedimiento
« Respuesta #5 en: Miércoles 15 de Octubre de 2003, 15:55 »
0
me gusta ese reto, pero en este instante no se me ocurre una solucion, pero veamos la dudas:
1) LES AX,numero
Esto carga el desplazamiento de numero en AX y su segmento en ES, No carga la parte baja en AX y la alta en ES, por lo tanto no seria corresta la suposicion.
2)movimiento directo de DX:AX a memoria
Creo que existe alguna instruccion que produce esa o una operacion similar pero no la recuerdo;


Despues una alternativa seria usar registros de 32bits como EAX,EBX,...pero cuando quieras trabajar con numeros mas grandes ya no funcionaria y seria la misma historia.


Hace algun tiempo tenia la tarea de multiplicar 3 numeros de 32Bits en el 68000MC, y hacerlo de forma iterativa consumia un tiempo enorme(practicamnete se colgaba), lo que hice fue dividir los numeros grandes resultantes en words, y aunque no era tan facil pues no lo termine, creo que podria ser una alternativa.

seth_los

  • Nuevo Miembro
  • *
  • Mensajes: 9
    • Ver Perfil
Re: Novato pide ayuda con su primer procedimiento
« Respuesta #6 en: Miércoles 14 de Abril de 2004, 00:53 »
0
Hola Colitroni tengo una version de puerba del emu8086 y me gustaria tener el serial
si me lo puedes pasar este es mi correo seth_los@yahoo.com


saludos gracias

imguerrero

  • Miembro activo
  • **
  • Mensajes: 64
  • Nacionalidad: es
    • Ver Perfil
    • http://www.blostec.com/
Re: Novato pide ayuda con su primer procedimiento
« Respuesta #7 en: Miércoles 14 de Abril de 2004, 13:35 »
0
En lugar de fomentar la pirateria, porque no usas compiladores com NASM que son gratuitos  :P