?? w.asm
字號(hào):
.286 ;采用286指令系統(tǒng)。原因后述。
data segment ;各變量的含義與VC版完全相同,
num1 db 0 ;聲明的先后順序也完全一致。
num2 db 0
num3 db 0
n db 0
char_a dw 0 ;char_a、char_b和char_c就是VC
char_b dw 0 ;版中的a、b和c三個(gè)字符型變量,
char_c dw 0 ;詳見VC版子程序hanoi的聲明。
x dw 0
y dw 0
data ends
code segment
main proc far ;void main()
assume cs:code,ds:data
mov ax,data ;{
mov ds,ax ; (int n;)
; cin>>n;
mov ah,1 ;輸入第1個(gè)數(shù)。
int 21h
cmp al,'0' ;如果無效,則退出。
jb exit
cmp al,'9'
ja exit
sub al,30h
mov n,al ;將第1個(gè)數(shù)暫存到n中。
int 21h ;輸入第2個(gè)數(shù),如果是回車,就把第1個(gè)數(shù)
cmp al,0dh ;當(dāng)成個(gè)位,直接開始(jmp begin)。
je begin
cmp al,'0' ;如果無效,則退出。
jb exit
cmp al,'9'
ja exit ; if(n<1 || n>99){exit(1);}
sub al,30h
mov bl,n ;如果第2個(gè)數(shù)有效,那么就把第1個(gè)數(shù)(已
imul bx,bx,10 ;暫存到n中)乘以10,加上第2個(gè)數(shù)。
mov ah,0 ;由于前面的imul是286指令,所以前面要
add ax,bx ;寫.286,以免出錯(cuò)。
mov n,al
mov ah,2 ;回車換行。
mov dl,0ah
int 21h
mov dl,0dh
int 21h
begin:
mov al,n
mov num1,al ; num1=n;
mov ah,0
push ax ;對(duì)子程序hanoi的調(diào)用——是用堆棧的方式傳
push 'a' ;遞參數(shù)的。
push 'b'
push 'c' ; hanoi(n,'a','b','c');
call get_sys_time ;輸出系統(tǒng)時(shí)間,形式為“秒:百分之一秒”。
call hanoi ;調(diào)用hanio子程序,開始遞歸。
pop ax ;出棧
pop ax
pop ax
pop ax
mov ah,2 ;回車換行
mov dl,0ah ; cout<<endl;
int 21h
mov dl,0dh
int 21h
call get_sys_time ;再輸出系統(tǒng)時(shí)間,以計(jì)算hanoi程序用時(shí)。
exit: ;退出程序。
mov ah,4ch
int 21h
main endp ;} //main結(jié)束。
get_sys_time proc near ;輸出系統(tǒng)時(shí)間。
mov ah,2ch ;調(diào)用功能2ch(獲取系統(tǒng)時(shí)間)。
int 21h
mov ch,dh ;dh存放當(dāng)前的秒數(shù)。
call outputch ;按十進(jìn)制輸出ch中的兩位數(shù)(秒數(shù))。
mov ah,2 ;中間三行輸出冒號(hào)。
mov dl,':'
int 21h
mov ah,2ch ;dl存放當(dāng)前百分之一秒數(shù)。
int 21h
mov ch,dl
call outputch ;輸出之。
ret
get_sys_time endp
hanoi proc near ;void hanoi(int n,char a,char b,char c)
call printstats ;{
; cout <<endl<<"n="<<n<<" abc="<<num1
; <<','<<num2<<','<<num3;
mov bp,sp ;sp不能直接用,所以要先傳給bp。
mov ax,[bp+2] ;讀取“進(jìn)度”。
mov char_c,ax
mov ax,[bp+4]
mov char_b,ax
mov ax,[bp+6]
mov char_a,ax
mov ax,[bp+8]
mov n,al
cmp n,1 ; if(n==1)
jne go_on
mov ax,char_a ; {
mov x,ax ; move子程序是用變量傳遞參數(shù)的,無須壓棧。
mov ax,char_c
mov y,ax
call move ; move(a,c);
jmp sub_end ; }
go_on: ; else
sub n,1 ; { //else開始。
mov al,n ; 把n減去1,存入進(jìn)度。
mov ah,0
push ax
mov ax,char_a
push ax
mov ax,char_c
push ax
mov ax,char_b
push ax
call hanoi ; hanoi(n-1,a,c,b);
pop ax ; 讀取進(jìn)度。
mov char_b,ax
pop ax
mov char_c,ax
pop ax
mov char_a,ax
pop ax
mov n,al
mov ax,char_a
mov x,ax
mov ax,char_c
mov y,ax
call move ; move(a,c);
mov al,n ; 保存進(jìn)度。
mov ah,0
push ax
mov ax,char_b
push ax
mov ax,char_a
push ax
mov ax,char_c
push ax
call hanoi ; hanoi(n-1,b,a,c);
pop ax ; 讀取進(jìn)度。
mov char_c,ax
pop ax
mov char_a,ax
pop ax
mov char_b,ax
pop ax
mov n,al
add n,1 ; 由于先前n已被減1,故此處要恢復(fù)n原值。
sub_end: ; } //else結(jié)束。
;call printstats ;cout <<endl<<"n="<<n<<" abc="<<num1
ret ; <<','<<num2<<','<<num3;
hanoi endp ;} //hanoi結(jié)束。
move proc near ;void move(char x,char y)
cmp x,'a' ;{
je subnum1 ; if (x=='a') {--num1;}
cmp x,'b' ; if (x=='b') {--num2;}
je subnum2
cmp x,'c' ; if (x=='c') {--num3;}
je subnum3
subnum1:
sub num1,1
jmp add_nums
subnum2:
sub num2,1
jmp add_nums
subnum3:
sub num3,1
jmp add_nums
add_nums:
cmp y,'a' ; if (y=='a') {++num1;}
je addnum1
cmp y,'b' ; if (y=='b') {++num2;}
je addnum2
cmp y,'c' ; if (y=='c') {++num3;}
je addnum3
addnum1:
add num1,1
ret
addnum2:
add num2,1
ret
addnum3:
add num3,1
ret
move endp ;}
printstats proc near ;本子程序作用在上文調(diào)用處已經(jīng)標(biāo)明。
mov ah,2
mov dl,0ah
int 21h
mov dl,0dh
int 21h
mov dl,'n'
int 21h
mov dl,'='
int 21h
mov ch,n
call outputch
mov dl,' '
int 21h
mov dl,'a'
int 21h
mov dl,'b'
int 21h
mov dl,'c'
int 21h
mov dl,'='
int 21h
mov ch,num1
call outputch
mov dl,','
int 21h
mov ch,num2
call outputch
mov dl,','
int 21h
mov ch,num3
call outputch
ret
printstats endp
outputch proc near ;本子程序是用來以十進(jìn)制形式,
push ax ;輸出ch中的數(shù)。
mov ah,0
mov al,ch ;將ch賦予al(實(shí)際上是ax)待除。
mov bl,10
div bl ;ax除以10,此時(shí)商(十位)在al中,
push ax ;余數(shù)(個(gè)位)在ah中。先保存一下ax。
mov ah,2
cmp al,0 ;如果商為0(只有個(gè)位),直接輸出。
je popax
mov dl,al ;否則,先輸出商,然后
add dl,30h
int 21h
popax:
pop ax
mov dl,ah ;再輸出余數(shù)。
add dl,30h
mov ah,2
int 21h
pop ax
ret
outputch endp
code ends
end main
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -