Autor
|
Tema: Ayuda en ensamblador, no sale del ciclo (Leído 5,486 veces)
|
Juan Martinez
Desconectado
Mensajes: 4
|
Tengo este programa, es para calcular el promedio de n números ingresados por el usuario, Corre todo bien hasta el momento de ingresar los datos, nunca sale del ciclo en el que se encuentra. Este es el código: .model small .stack 64 .data ;......................................... VAL1 DB ? msj1 DB 0AH,0DH, Cuantos numeros deseas introducir? : , $ msj2 DB 0AH,0DH, Numero: , $ msj3 DB 0AH,0DH, Promedio: , $ buffer DB 3,4 DUP(?) ;......................................... .code empezar proc far mov ax,@data mov ds,ax mov es,ax LEA DX,msj1 MOV AH,09H INT 21H MOV AH,0AH INT 21H SUB AL,30H MOV CL,AL MOV BL,AL MOV AL,00 MOV VAL1,AL proc1: LEA DX,msj2 MOV AH,09H INT 21H MOV AH,0AH LEA DX,buffer INT 21H SUB AL,30H ADD AL,VAL1 MOV VAL1,AL LOOP proc1 proc2: LEA DX,msj3 MOV AH,09H INT 21H MOV AX,00 MOV AL,VAL1 DIV BL ADD AX,3030H MOV DX,AX MOV AH,09H INT 21H mov ax,4c00h ;fin del programa con interrupcion int 21h empezar endp end empezar
Ojala y me puedan ayudar, gracias MOD: Etiqueta GeSHi
|
|
« Última modificación: 15 Mayo 2017, 18:38 pm por MCKSys Argentina »
|
En línea
|
|
|
|
Serapis
|
Loop Proc1, te devuelve a Proc1, pero antes decrementa el registro CX en una unidad, cuando CX llega a 0, deja de hacer el salto a Proc1... Entonces se trata de saber que valor ingresas en el registro CX. Si miramos el código, al registro CX, no se le ha asignado explícitamente ningún valor, luego contendrá la basurilla que reste de otro programa, si más adelante colocas un valor en CL, pero no sabemos cual hay en CH, luego... Típicamente un bucle lleva la estructura: MOV CX, Contador Inicio: ... codigo a repetir LOOP Inicio cuando CX valga 0 ...codigo despues del bucle
Prueba a asignar a contador un valor arbitrario cada vez, por ejemplo 13, ejecuta paso a paso y verás como el bucle retorna una y otra vez al 'Inicio', y cólo cuando CX valga 0, ejecuta el código tras el bucle. Dado que dices "n números ingresados", Contador debería valer ese 'n'. Si 'n' no es conocido, porque se debe ejecutar una y otra vez hasta que el usuario tome una decisión al respecto, entonces el bucle que debe usarse no va por Loop, mejor LOOPNE, o LOOPNZ por ejemplo haciendo que cuando el usuario quiera terminar pulse una determinada tecla, tu haces un TEST entre el valor de la letra esperada (Q) y el valor de la letra introducida por el usuario, y acto seguido saltas en función del resultado del test... a diferencia de otros lenguajes, el ensambalador permite una infinidad de opciones para hacer lo mismo. compruebas si la tecla pulsada es la deseada, en cuyo caso puedes hacer un XOR CX CX (que cambia su contenido a 0, y entonces usas LOOPNZ), cuando CX sea 0, saldrá del bucle... en este caso el salto está condicionado, por la pulsación de una tecla concreta (la 'Q' por ejemplo de "Quit")... Y tu código quedaría controlado tal que así: MOV CX, 1 <-- poner un valor en el contador Inicio: .... tu codigo (entrada de datos por parte del usuario) TEST teclaesperada "Q", contra valor entrado JNE FinOpera <--- SALTAR si igual (o si no cero JNZ) INC CX .... tu código para sumar el nuevo valor entrado (distinto de Q) FinOpera: <--- punto de salto si usuario pulsa tecla Q (salir) LOOPNZ Inicio
Al llegar a Loop, si la tecla introducida es distinta de la esperada, se incrementa CX, entonces CX=2, luego Loop decrementa CX, y CX vuelve a valer 1. En cambio, si el númnero recibido es igual al valor ASCII de Q (81) el test devuelve 'True', y por tanto saltamos el incremento de CX, como vale 1, cuando llegue a LOOP decrementa 1, vale 0 y por tanto sale ya del bucle. En resumen: - Fíjate que tu no tienes claro (yo por lo menos leyendo tu código), el valor de CX, así que no hay forma de saber cuando llega a cero... - LOOP decrementa CX en 1 cada vez que se ejecuta y si CX vale 0, sale fuera del bucle. - Si el condicional de salida depende de algún factor más, puedes o bien controlar directamente CX (como te muestro en el ejemplo), o bien usar otras variantes de LOOP, LOOPE, LOOPZ, LOOPNE, LOOPNZ, o incluso alguna instrucción condicional de salto... (por ejemplo JNE, podría saltar fuera del bucle directamente, es buena práctica al inicio, tener una única salida de un procedimiento, cuando tengas buen control del código, no te importará que se salga desde más de una parte)...
|
|
« Última modificación: 15 Mayo 2017, 21:57 pm por NEBIRE »
|
En línea
|
|
|
|
Juan Martinez
Desconectado
Mensajes: 4
|
Muchas gracias por tu ayuda entonces quedaria asi: MOV CX,1 proc1: LEA DX,msj2 MOV AH,09H INT 21H MOV AH,0AH LEA DX,buffer INT 21H SUB AL,30H TEST JNE FinOpera INC CX ADD AL,VAL1 MOV VAL1,AL FinOpera: LOOPNZ proc1
o que mas es lo que tengo que modificar? · Los códigos deben ir en etiquetas GeSHi (segunda advertencia) >aquí las reglas del foro -Engel Lex
|
|
« Última modificación: 15 Mayo 2017, 23:52 pm por engel lex »
|
En línea
|
|
|
|
Serapis
|
Antes de nada: Date cuenta que te han corregido el código para encerrarlo entre (USA) etiquetas CODE, hazlo tú en lo sucesivo... para delimitar el código y que resulte más legible. En los botoncitos del editor (de mensajes), a la derecha pone: "Código Geshi", despliega el combo y elige el lenguaje pertinente, al caso ASM. Es la 2ª advertencia que te dan, no se que pasará a la 3ª Bueno, lo que veo es que o no conoces la instrucción Test, o se te ha pasado (piensa que yo te he puesto algo intermedio entre ensamblador y pseudocódigo, me gusta que la gente soluciones su tema, pero pensando un poco no solo copiando y pegando)... La instrucción TEST, es muy similar a la instrucción CMP y como ella, lleva dos operandos (en el mensaje previo, he expresado ambos operandos en forma de pseudocódigo), Destino y fuente, técnicamente es un AND (y por tanto igual de rápida) y a diferencia de AND y CMP, no almacena el resultado en destino, solo altera (si así sucede), los banderines de estados (los mismos que AND, ya que el hardware implementa esta instrucción partiendo de AND, técnicamente es un AND (si no es un procesador RISC), sin la microoperación copiar el resultado en destino). Así en TEST, uno de sus operandos puede contener la mascara con la que se compara. Si al caso como yo decía la letra Q (ASCII=81), si es un valor inmediato entonces debe ser el operando origen, en el otro operando puedes poner un registro, o una dirección de memoria, donde yace el valor de la letra con la que se evalúa. Ejemplo: TEST Al, 51H - 30H <--- Igual que a los números 0-9 (ASCII 48-57, les restamos 48 Para que sean en el rango 0-9, al valor inmediato también le tenemos que restar, para que coincida que el valor leído (y al que se le descontó, 48 (30H))... obviamente, la resta puedes ponerla ya como un resultado, pero si nu ncomentario, más adelabnte puede que te preguntes de dónde viene compararlo con ese valor... hasta que tengas costumbre, los comentarios 'tontos', te serán necesarios, ponlos... p.d.: Una última cosa... no es preciso, que me envíes un mensaje privado para que responda en tu tema, ya cuando entro procuro mirar temas que entienda 'tener a medias'... siempre que mi tiempo libre me lo permita.
|
|
« Última modificación: 16 Mayo 2017, 02:21 am por NEBIRE »
|
En línea
|
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
[Ayuda]Ciclo Foreach PHP
PHP
|
rolly21102
|
4
|
5,020
|
16 Junio 2010, 03:05 am
por bomba1990
|
|
|
Ayuda con un ciclo
Java
|
xAgramonx
|
3
|
3,374
|
25 Noviembre 2010, 19:30 pm
por xAgramonx
|
|
|
Ayuda con función en ciclo FOR, nadieee ????
PHP
|
mokoMonster
|
5
|
4,067
|
30 Enero 2011, 15:38 pm
por ~ Yoya ~
|
|
|
Ayuda con ciclo for C++
« 1 2 »
Programación C/C++
|
andrex.125
|
12
|
5,648
|
11 Mayo 2013, 07:38 am
por andrex.125
|
|
|
ayuda con ciclo while!
Programación C/C++
|
el1000erroresxd
|
3
|
3,114
|
5 Junio 2016, 03:37 am
por AlbertoBSD
|
|