Red de conocimiento informático - Conocimiento sistemático - Problema de las ocho reinas en la compilación

Problema de las ocho reinas en la compilación

Función del programa: utilice el método de búsqueda en profundidad para resolver el problema de las ocho reinas e imprimir los resultados.

;El número de columnas y filas están etiquetados del 1 al 8 respectivamente. Por lo tanto, nueve se usa en la posición de las Ocho Reinas

Experiencia de depuración: la depuración de ensamblados es realmente problemática, a diferencia del lenguaje C, donde se puede saber agregando un printf en cualquier lugar

; esta mal? Incluso si saltas, no sabes dónde está el bucle infinito, por lo que es muy inconveniente depurarlo.

.model es pequeño, stdcall

; debido a que la posición de la reina es de un solo dígito, se agrega 30H a los caracteres de salida impresos.

printResult macro

local nuevamente, imprimir, primero

presionar si no puede cambiar su valor.

mov ah, 02h; el estado de salida permanece sin cambios.

mov cx, 2 ; Los resultados son simétricos, por lo que se ingresan dos resultados.

De nuevo:

mov si, 1

imprimir:

mov dl, reina[si]

cmp cx, 2

je primero

mov bl, 9

sub bl, dl

mov dl, bl

primero:

añadir dl, 30h

int 21h

inc si

cmp si, 9 al 9 es; para decir que ya está hecho.

jnz print

mov dl, ' '; Genera dos espacios para que se vea bien.

int 21h

int 21h

Bucle nuevamente

pop si

endm

.data

; Cambió todo, ¿por qué eres tan tacaño? Es más conveniente usar 9, es solo un byte, ¡no hay necesidad de ser tan tacaño!

reina db 9 dup(0)

usado db 9 dup(0)

Nresultado dw 0;

prompt db "Las posiciones son:", 0ah, 0dh, '$'

over db 0ah, 0dh, "El número del resultado es $"

.code

; Función Función: Imprime el número binario en el registro del eje en decimal.

printaxd proc cerca

mov bx, 10000d; el número máximo de dos bytes es aproximadamente 30000.

mov ch, 0; el primer número que se imprimirá aún no ha aparecido (no es necesario imprimir el mayor distinto de cero)

mov cl, 5; dígitos, entonces divide por uno *** cinco veces.

mov si, ax; Jaja, los registros son muy inteligentes.

Continuar:

mov ax, si

mov dx, 0; debido a que es división, asegúrese de que el valor absoluto del bit alto sea el más pequeño.

div bx

dec cl; divide una vez y disminuye una vez.

mov di, ax; elimina el cociente después de la división y da la posición a bx/10

mov si, dx;

;Realiza bx/10.

mov ax,bx

mov bx,10;Recuerda que la multiplicación y división no se pueden hacer con números inmediatos.

mov dx, 0; De hecho, el valor máximo de dl es 9, que es menor que 10, pero por razones de seguridad y costumbre, utilice esta oración.

div bx

mov bx, ax

mov ax, di

cmp cl, 0; , sea 0 o no, tienes que imprimirlo.

jz next

o ch, al

jz go

next :

mov ch, 1; imprimiendo ahora

mov dl, al

add dl, 30h

mov ah, 02h

int 21h

cmp cl, 0

jnz go

ret;

printaxd endp

proc principal lejos

mov ax, @data

mov ds, ax

mov es, ax

mov dx, indicación de compensación

mov ah, 09h

int 21h

mov si, 1 por supuesto desde; Comience con la primera columna.

go:

inc queen[si]; cuando la columna actual baja un paso.

; Prueba si has salido de la cuadrícula de 8*8

cmp queen[si], 9

jnz queda

; Simplemente salga de Grid, establezca la columna actual en 0, deje la fila anterior vacía y continúe.

mov queen[si], 0

dec si

; no puedes hacer esto si tienes problemas.

; Cancelar la fila ocupada.

mov al, queen[si]; no sé por qué no puedo usar movzx di, queen[si]

cbw

mov di , ax

mov used[di], 0

; si se completó la búsqueda.

cmp si,1

jnz go

Nota de depuración: ¿por qué no salir en 5? Después de cambiar a 4, el resultado es correcto. ¡Última pregunta!

;¡Sí! ¡Eso es todo!

;Entonces la condición de salida es que cuando la primera columna sea 4, quieras dar un paso adelante basado en la simetría

;Debes salir.

cmp queen[si], 4; Aprovechando la simetría, si la primera columna cuenta hasta 5 filas, no es necesario contar.

je exit

jmp go

quedarse: ;quedarse en la plaza, entonces es solo una cuestión de si satisface el requisito de no estar en la misma fila en la misma diagonal.

mov al, queen[si]; de alguna manera no puedo usar movzx di, queen[si]

cbw

mov di , ax

cmp used[di], 1; si es 1, significa que se ha utilizado la fila actual de la columna actual.

je go

; recorre las reinas en la misma diagonal.

mov di,si

dec di; bx apunta a la columna que se va a comparar con la columna actual.

Verificar:

cmp di, 0

je checkover

mov dx, si dx guarda la diferencia entre la columna actual y; la diferencia de la columna de verificación. La diferencia máxima es 7, por eso decimos que está contenida en dl.

sub dx, di

mov al, queen[si]; guarda la diferencia entre dos líneas.

sub al, reina[di]

cmp al, dl; filas iguales u opuestas en la misma diagonal.

je go

neg al ; Encuentra números negativos.

cmp al, dl

je go

dec di

jmp check

checkover:

;OK, ahora puede quedarse.

cmp si,8

jz result

;Si no es la última columna.

mov al, queen[si]; de alguna manera no puedes usar movzx di, queen[si]

cbw

mov di, ax

mov used[di], 1; Permanecer en esta línea toma el control.

inc si

jmp go

resultado: ; resultado, pero según la simetría, dos resultados.

add Nresult, 2

printResult

mov queen[si], 0

dec si

; Estas cuatro líneas son la primera vez que diseñan lagunas y he estado pensando en ellas durante mucho tiempo. desplazamiento sobre

mov ah, 09h

int 21h

mov ax, Nresult

llamada printaxd

mov ah, 01h; pausa

int 21h

mov ah, 4ch

int 21h

final principal

end main

Si lo anterior no funciona, intente esto nuevamente y use masm5 para depurar

.

MODELO

.286

.CODE

ORG 100H <

REINA: PUSH '$'

PUSH '

MOV BP, SP

LEA DX, [BP-08]

NEWL: MOV AH, '1'

NEWC : MOV CL, 00

MOV SI, SP

ISOK: CMP SI, BP

JE SAVE

LODSB

SUB AL, AH

JZ SIGUIENTE

INC CX

CMP AL, CL

JE SIGUIENTE

AÑADIR AL, CL

JZ SIGUIENTE

JMP ISOK

GUARDAR: PUSH AX

INC SP

CMP SP, DX

JNE NEWL

MOV AH, 9

INT 21H

VOLVER: DEC SP

POP AX

SIGUIENTE: INC AH

CMP AH, '1' 08

JNE NEWC

CMP SP, BP

JNE VOLVER

INT 20H

END QUEEN