當前位置:編程學習大全網 - 編程語言 - 匯編的八皇後問題

匯編的八皇後問題

程序功能:用深度優先搜索法解決八皇後問題並打印結果.

;列數行數分別用1-8標記.所以八皇後的位置申請了9個

;調試感慨:匯編調試實在麻煩,不像C中在任何地方加個printf就可以知道

;哪錯了.跳來跳去的,不知哪裏死循環了,實在不好調試.

.model small,stdcall

;由於皇後位置都是壹位數,所以加上30H後作字符打印出.

printResult macro

local again,print,first

push si ;不能改變它的值.

mov ah,02h ;輸出狀態不變.

mov cx,2 ;對稱的結果,所以打兩個結果.

again:

mov si,1

print:

mov dl,queen[si]

cmp cx,2

je first

mov bl,9

sub bl,dl

mov dl,bl

first:

add dl,30h

int 21h

inc si

cmp si,9 ;到第9個就是說打完了.

jnz print

mov dl,' ' ;輸出兩個空格,為好看.

int 21h

int 21h

loop again

pop si

endm

.data

;改來改去,何必那麽小氣呢?用9個多方便,就壹個字節,不必這麽小氣!

queen db 9 dup(0)

used db 9 dup(0)

Nresult dw 0 ;結果的個數.

prompt db "The positions are:",0ah,0dh,'$'

over db 0ah,0dh,"The number of the result is $"

.code

;函數功能:把存在ax寄存器裏的二進制數用十進制打印出來.

printaxd proc near

mov bx,10000d ;二個字節的數最大就3萬多.

mov ch,0 ;還沒出現第壹個要打印的數(最高位的非0不需要打印)

mov cl,5 ;最多有五位,所以壹***除五次.

mov si,ax ;哈哈,寄存器太聰明了.

go:

mov ax,si

mov dx,0 ;既然是除法,就要保證高位的絕對值最小.

div bx

dec cl ;除壹次就減壹次.

mov di,ax ;除完就把商移走,位置讓出來給bx/10

mov si,dx ;保證余數.

;實現bx/10.

mov ax,bx

mov bx,10 ;記住乘除法運算不能用立即數.

mov dx,0 ; 實際上dl的最大值也就是9小於10,但為了保險和習慣,還是用這壹句.

div bx

mov bx,ax

mov ax,di

cmp cl,0 ;如果到最後壹位了,無論是0還是不為0,都要打印了.

jz next

or ch,al

jz go

next:

mov ch,1 ;有打印的了

mov dl,al

add dl,30h

mov ah,02h

int 21h

cmp cl,0

jnz go

ret ; This line cann't be forgotten.

printaxd endp

main proc far

mov ax,@data

mov ds,ax

mov es,ax

mov dx,offset prompt

mov ah,09h

int 21h

mov si,1 ;當然是從第壹列開始.

go:

inc queen[si] ;當前列向下走壹步.

;測試是否走出8*8的格子了

cmp queen[si],9

jnz stay

;剛好踏出格子,就把當前列置0,把上壹列所在行置空,然後繼續go.

mov queen[si],0

dec si

;取消所占的行.

mov al,queen[si] ;不知何以不能用movzx di,queen[si]

cbw

mov di,ax

mov used[di],0

;是否完成搜索.

cmp si,1

jnz go

;調試記語:為什麽為5時不退出呢?改成4後結果居然對了.最後壹個疑問了!

;對!原來如此!退出是要在queen[1]為5時,當4變成5時,這個增加的過程

;在go的第壹句,也就是說此時還為4.

;於是退出條件就是當此時第壹列為4而又要向前址走壹步時根據對稱性

;就要退出了.

cmp queen[si],4 ;利用對稱性,如果第壹列算到5行,就不用算了.

je exit

jmp go

stay: ;留在方格內,那麽就剩下是否滿足不在同壹行同壹斜行的問題了.

mov al,queen[si] ;不知何以不能用movzx di,queen[si]

cbw

mov di,ax

cmp used[di],1 ;如果為1就說明當前列的當前行已使用.

je go

;循環檢查是否有在同壹斜行的皇後.

mov di,si

dec di ; bx指向與當前列比較的列.

check:

cmp di,0

je checkover

mov dx,si ;dx裝著當前列與檢測列的差.,差最大不過7,所以也可以說是裝在dl中.

sub dx,di

mov al,queen[si] ;al放兩列的行之差.

sub al,queen[di]

cmp al,dl ;相等或相反就是在同壹斜行.

je go

neg al ;求負數.

cmp al,dl

je go

dec di

jmp check

checkover:

;好,現在可以留下來了.

cmp si,8

jz result

;如果不是最後壹列.

mov al,queen[si] ;不知何以不能用movzx di,queen[si]

cbw

mov di,ax

mov used[di],1 ;留下來這壹行就占住了.

inc si

jmp go

result: ;好,壹個結果出來了,根據對稱,實際出來兩個結果.

add Nresult,2

printResult

mov queen[si],0

dec si

;這四行初為設計上的漏洞,想了老半天.

mov al,queen[si] ;不知何以不能用movzx di,queen[si]

cbw

mov di,ax

mov used[di],0

jmp go

exit:

mov dx,offset over

mov ah,09h

int 21h

mov ax,Nresult

call printaxd

mov ah,01h ; to pause

int 21h

mov ah,4ch

int 21h

main endp

end main

要是上面那個不行的話,妳再試壹試這個,用masm5調試

.MODEL

.286

.CODE

ORG 100H

QUEEN: 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 NEXT

INC CX

CMP AL,CL

JE NEXT

ADD AL,CL

JZ NEXT

JMP ISOK

SAVE: PUSH AX

INC SP

CMP SP,DX

JNE NEWL

MOV AH,9

INT 21H

BACK: DEC SP

POP AX

NEXT: INC AH

CMP AH,'1'+08

JNE NEWC

CMP SP,BP

JNE BACK

INT 20H

END QUEEN

  • 上一篇:精神依賴的神經生物學基礎
  • 下一篇:程序員電腦桌面被總經理吐槽:這樣的人,做事不靠譜!
  • copyright 2024編程學習大全網