پازل برجهای Hanoi با اسمبلی

یک procedure یا تابع بازگشتی تابعی است که خودش را به صورت مستقیم یا غیر مستقیم call میکند.با اسمبلی 86×80 خیلی راحت میتوان توابع بازگشتی را نوشت. اگر پارامترها و متغیر های local به Stack ارسال شوند ,میتوان با هر بار فراخوانی تابع فضای دسترسی جدیدی برای پارامترها و متغیر های جدید در استک ایجاد کرد.اگر رجیسترها به درستی در استک ذخیره و بازیابی شوند میتوان از آنها در هر فراخوانی تابع استفاده کرد بدون اینکه مقادیر از بین بروند.

حل پازل برجهای هانوی به این صورت است که در صورتی که فقط یک دیسک وجود داشته باشد با یک حرکت ساده از میله مقصد به میله مبدأ دیسک جابجا میشود.

اگر تعداد بیشتر از یک دیسک وجود داشته باشد آنگاه Number -1 دیسک بالا به میله کمکی انتقال می یابد و آخرین دیسک که بزرگترین دیسک هم هست به میله مقصد انتقال می یابد و در آخر Number -1 دیسک کوچکتر به مقصد انتقال می یابند .

شبه کد :

 

procedure Move(NbrDisks, Source, Destination, Spare);
   begin
       if NbrDisks = 1
       then
            display "Move disk from ", Source, " to ", Destination
       else
            Move(NbrDisks -- 1, Source, Spare, Destination);
            Move(1, Source, Destination, Spare);
            Move(NbrDisks -- 1, Spare, Destination, Source);
       end if;
   end procedure Move;
   begin {main program}
          prompt for and input Number;
          Move(Number, 'A', 'B', 'C');
   end;

فقط باید دقت کنید که استک رو به آدرسهای کمتر پر میشود یعنی با هر بار push کردن ابتدا sp کاهش می یا بد سپس مقدار در استک قرار میگیرد .

برنامه زبان اسمبلی :

 

;***************************************
;*                                     *
;*          Towers of Hanoi            *
;*                                     *
;*    https://tjs87.wordpress.com       *
;*                                     *
;***************************************

org 100h

    mov     ah,9        ;print msg
    lea     dx,msg
    int     21h

    mov     ah,1        ;reading number of disks
    int     21h 

    sub     al,'0'      ;stor as input patameter
    mov     ah,0
    mov     disks,ax

    mov     ah,2        ;line feed and carriage retutrn
    mov     dl,lf
    int     21h
    mov     dl,cr
    int     21h 

;Passing Parameters
    mov     ax,disks    ;Argument 1 : Number of disks
    push    ax
    mov     al,'A'      ;Argument 2 : Source
    push    ax
    mov     al,'B'      ;Argument 3 : Destination
    push    ax
    mov     al,'C'      ;Argument 4 : Spare
    push    ax

    call    Move
    add     sp,8        ;remove parameters from stack

    ret                 ;Return to OS

;***************< Procedure >***************    

Move    proc    near
    push    bp         ;save Base Pointer
    mov     bp,sp      ;bp = sp
    push    ax         ;save register

    cmp     [bp+10],1  ;if n == 1
    jne     _01        ;display Move disk from Source to Destination

    push    ax
    mov     ah,2
    mov     dx,[bp+8]
    int     21h

    mov     dl,'>'
    int     21h

    mov     dx,[bp+6]
    int     21h

    mov     dl,lf
    int     21h
    mov     dl,cr
    int     21h

    pop     ax
    jmp     ENDPROC
_01:
    mov     ax,[bp+10]
    dec     ax        ;NbrDisks - 1
    push    ax  

    push    [bp+8]
    push    [bp+4]
    push    [bp+6]

    call    Move      ;Move(NbrDisks-1,Source,Spare,Destination)
    add     sp,8

    push    1
    push    [bp+8]
    push    [bp+6]
    push    [bp+4]

    call    Move      ;Move(1,Source,Destination,Spare)
    add     sp,8

    push    ax
    push    [bp+4]
    push    [bp+6]
    push    [bp+8]

    call    Move      ;Move(NbrDisks-1,Spare,Destination,Source)
    add     sp,8

ENDPROC:
    pop     ax
    pop     bp
    ret
Move    endp
;*******************************************

           ;data
lf  equ 0ah          ;Line feed
cr  equ 0dh          ;Carriage return

msg     db  'How many disks?','$'
disks   dw  1

پایان!

Advertisements

دربارهٔ DeltaCode

Somewhere near the sky Far away from people Far away from noise Somewhere near yourself

Posted on ژانویه 24, 2011, in برنامه نویسی and tagged , , , , , , . Bookmark the permalink. 5 دیدگاه.

  1. «فقط باید دقت کنید که استک رو به آدرسهای کمتر پر میشود یعنی با هر بار push کردن ابتدا sp کاهش می یا بد سپس مقدار در استک قرار میگیرد . » یعنی چی ؟

  2. مثلا اگر در ابتدا sp برابر 0xFFFF باشد با نوشتن دستور push مقدار sp برابر 0xFFFD میشود و به همین ترتیب با هر بار پوش کردن از اشاره گر استک کم میشود .
    با نوشتن دستور pop مقدار sp افزایش پیدا میکند مثلا اگر 0xFFF2 باشد برابر 0xFFF4 میشود .
    در اسمبلی مدیریت استک با برنامه نویس است هر گونه دستکاری اشتباهی باعث گم شدن آدرس برگشت میشود بقیه اش رو خودت حدس بزن . . .

  3. ایول…نمی دونستم انقدر اسمبلی بلدی…

  4. میبینید عجب شاگردایی تربیت کردم !

  5. بنده این ترم شاگرد استاد عباسپور بودم .
    در ضمن بچه جون خودت رو جای استاد جا نزن .

پاسخی بگذارید

در پایین مشخصات خود را پر کنید یا برای ورود روی شمایل‌ها کلیک نمایید:

نشان‌وارهٔ وردپرس.کام

شما در حال بیان دیدگاه با حساب کاربری WordPress.com خود هستید. بیرون رفتن / تغییر دادن )

تصویر توییتر

شما در حال بیان دیدگاه با حساب کاربری Twitter خود هستید. بیرون رفتن / تغییر دادن )

عکس فیسبوک

شما در حال بیان دیدگاه با حساب کاربری Facebook خود هستید. بیرون رفتن / تغییر دادن )

عکس گوگل+

شما در حال بیان دیدگاه با حساب کاربری Google+ خود هستید. بیرون رفتن / تغییر دادن )

درحال اتصال به %s

%d وب‌نوشت‌نویس این را دوست دارند: