loops - programas - ¿Cómo hacer un ciclo en el lenguaje ensamblador x86?
programas en lenguaje ensamblador explicados (6)
Estaba buscando la misma respuesta y encontré esta información de wiki útil: Instrucciones de bucle
La instrucción de ciclo disminuye ECX y salta a la dirección especificada por arg a menos que la disminución de ECX provoque que su valor se vuelva cero. Por ejemplo:
mov ecx, 5
start_loop:
; the code here would be executed 5 times
loop start_loop
loop no establece ningún indicador.
loopx arg
Estas instrucciones de ciclo disminuyen ECX y saltan a la dirección especificada por arg si se cumple su condición (es decir, se establece un indicador específico), a menos que la disminución de ECX provoque que su valor se convierta en cero.
loope loop si es igual
loopne loop si no es igual
loopnz loop si no es cero
loopz loop si cero
Fuente: ensamblaje X86, flujo de control
He escrito el código hasta ahora:
.code
main
Clrscr
mov dh,10 ;row 10
mov dl,20 ;column 20
call Gotoxy ;locate cursor
PromptForIntegers
WriteString ;display string
ReadInt ;input integer
ArraySum
WriteString ;display string
WriteInt ;display integer
DisplaySum ENDP
END main
¿Cómo hago para repetir los mismos pasos tres veces usando un bucle, borrando la pantalla después de cada iteración?
Necesita usar comandos condicional jmp. Esta no es la misma sintaxis que estás usando; parece MASM, pero usando GAS aquí hay un ejemplo de algún código que escribí para calcular gcd:
gcd_alg:
subl %ecx, %eax /* a = a - c */
cmpl $0, %eax /* if a == 0 */
je gcd_done /* jump to end */
cmpl %ecx, %eax /* if a < c */
jl gcd_preswap /* swap and start over */
jmp gcd_alg /* keep subtracting */
Básicamente, comparo dos registros con la instrucción cmpl (compare larga). Si es menor, la instrucción JL (saltar menos) salta a la ubicación de preswap, de lo contrario salta a la misma etiqueta.
En cuanto a limpiar la pantalla, eso depende del sistema que estés usando.
Otro método más está usando la instrucción LOOP:
mov cx, 3
myloop:
; Your loop content
loop myloop
La instrucción de bucle automáticamente disminuye cx, y solo salta si cx! = 0. También hay variantes LOOPE, y LOOPNE, si desea hacer una verificación adicional para que su bucle salga temprano.
Si desea modificar cx durante su bucle, asegúrese de insertarlo en la pila antes del contenido del bucle y retírelo después de:
mov cx, 3
myloop:
push cx
; Your loop content
pop cx
loop myloop
Usa el registro CX para contar los bucles
mov cx, 3 startloop: cmp cx, 0 jz endofloop push cx loopy: Call ClrScr pop cx dec cx jmp startloop endofloop: ; Loop ended ; Do what ever you have to do here
Esto simplemente hace un bucle alrededor de 3 veces llamando a ClrScr
, presionando el registro CX en la pila, comparando con 0, saltando si ZeroFlag está configurado y luego salta a endofloop
. Observe cómo el contenido de CX es empujado / reventado dentro / fuera de la pila para mantener el flujo del ciclo.
.model small
.stack 100h
.code
Main proc
Mov cx , 30 ; //that number control the loop 30 means the loop will
;excite 30 time
Ioopfront:
Mov ah , 1
Int 21h
Loop loopfront;
este bacalao tendrá 30 caracteres
mov cx,3
loopstart:
do stuff
dec cx ;Note: decrementing cx and jumping on result is
jnz loopstart ;much faster on Intel (and possibly AMD as I haven''t
;tested in maybe 12 years) rather than using loop loopstart