Tower of Hanoi in assembly x86 using arrays

1.1k views Asked by At

Hi every one I am trying to do a tower of Hanoi in assembly x86 but I am trying to use arrays. So this code gets a number from user as a parameter in Linux, then error checks a bunch of stuff. So now I just want to make the algorithm which use the three arrays i made (start, end, temp) and output them step by step. If someone can help it would be greatly appreciated. `

%include "asm_io.inc"

segment .data                                               ; where all the predefined variables are stored

    aofr: db "Argument out of Range", 0                     ; define aofr as a String "Argument out of Range"
    ia: db "Incorrect Argument", 0                          ; define ia as a String "Incorrect Argument"
    tma: db "Too many Arguments", 0                         ; define tma as a String "Too many Arguments"
    hantowNumber dd 0                                       ; define hantowNumber this is what the size of the tower will be stored in

    start: dd 0,0,0,0,0,0,0,0,9                             ; this array is where all the rings start at
    end: dd 0,0,0,0,0,0,0,0,9                               ; this array is where all the rings end up at
    temp: dd 0,0,0,0,0,0,0,0,9                              ; this array is used to help move the rings
    test: dd 0,0,0,0,0,0,0,0,9

    ; The next couple lines define the strings to show the pegs and what they look like

    towerName: db "      Tower 1                 Tower 2                 Tower 3      ", 10, 0
    lastLineRow: db "XXXXXXXXXXXXXXXXXXX     XXXXXXXXXXXXXXXXXXX     XXXXXXXXXXXXXXXXXXX        ", 10, 0
    buffer: db "     ", 0

    fmt:db "%d",10,0


segment .bss                                                ; where all the input variables are stored


segment .text
    global  asm_main                                        ; run the main function
    extern printf


asm_main:
    enter   0,0                                             ; setup routine
    pusha

    mov edx, dword 0                                        ; set edx to zero this is where the hantowNumber is saved for now
    mov ecx, dword[ebp+8]                                   ; ecx has how many arguments are given
    mov eax, dword[ebp+12]                                  ; save the first argument in eax
    add eax, 4                                              ; move the pointer to the main argument
    mov ebx, dword[eax]                                     ; save the number into ebx

    push ebx                                                ; reserve ebx
    push ecx                                                ; reserve ecx

    cmp ecx, dword 2                                        ; compare if there are more the one argument given
    jg TmA                                                  ; if more then one argument is given then jump Too many Argument (TmA)

    mov ecx, 0                                              ; ecx = 0
    movzx eax, byte[ebx+ecx]                                ; eax is the first character number from the inputed number
    sub eax, 48                                             ; subtract 48 to get the actual number/letter/symbol
    cmp eax, 10                                             ; check if eax is less then 10
    jg IA                                                   ; if eax is greater then 10 then it is a letter or symbol


    string_To_int:                                          ; change String to int procedure
        add edx, eax                                        ; put the number in edx
        inc ecx                                             ; increase counter (ecx)
        movzx eax, byte[ebx+ecx]                            ; move the next number in eax
        cmp eax, 0                                          ; if eax = 0 then there are no more numbers
        mov [hantowNumber], edx                             ; change hantowNumber to what ever is in edx
        je rangeCheck                                       ; go to rangeCheck to check if between 2-8
        sub eax, 48                                         ; subtract 48 to get the actual number/letter/symbol 
        cmp eax, 10                                         ; check if eax is less then 10
        jg IA                                               ; if eax is greater then 10 then it is a letter or symbol
        imul edx, 10                                        ; multiply edx by 10 so the next number can be added to the end
        jmp string_To_int                                   ; jump back to string_To_int if not done 


    rangeCheck:                                             ; check the range of the number
        cmp edx, dword 2                                    ; compare edx with 2
        jl AofR                                             ; if hantowNumber (edx) < 2 then go to Argument out of Range (AofR)

        cmp edx, dword 8                                    ; compare edx with 8
        jg AofR                                             ; if hantowNumber (edx) > 8 then go to Argument out of Range (AofR)


    mov ecx, [hantowNumber]                                 ; move the number enterd by user in ecx
    mov esi, 28                                             ; esi == 28 for stack pointer counter
    setStart:                                               ; set the first array the starting peg
        mov [start+esi], ecx                                ; put ecx into the array
        sub esi, 4                                          ; take one away from stack pointer conter
        dec ecx                                             ; take one away from ecx so the next number can go in to the array
        cmp ecx, 0                                          ; compare ecx with 0
        jne setStart                                        ; if ecx != 0 then go to setStart loop


; This is the section where the algoritham should go for tower of hanoi 
    mov ecx, [hantowNumber]
    towerAlgorithm:
        cmp ecx, 0
        jg Exit                                            ; jump to Exit at the end of the program
        dec ecx

IA:
    mov eax, ia                                             ; put the string in eax
    push eax                                                ; reserve eax
    call print_string                                       ; output the string that is in eax
    call print_nl                                           ; print a new line after the output
    pop eax                                                 ; put eax back to normal
    add esp, 4                                              ; takes 4 from stack
    jmp Exit                                                ; jump to Exit at the end of the program


AofR:
    mov eax, aofr                                           ; put the string in eax
    push eax                                                ; reserve eax
    call print_string                                       ; output the string that is in eax
    call print_nl                                           ; print a new line after the output
    pop eax                                                 ; put eax back to normal
    add esp, 4                                              ; takes 4 from stack
    jmp Exit                                                ; jump to Exit at the end of the program


TmA:
    mov eax, tma                                            ; put the string in eax
    push eax                                                ; reserve eax
    call print_string                                       ; output the string that is in eax
    call print_nl                                           ; print a new line after the output
    pop eax                                                 ; put eax back to normal
    add esp, 4                                              ; takes 4 from stack
    jmp Exit                                                ; jump to Exit at the end of the program


Exit:                                                       ; ends the program when it jumps to here
    add esp, 9                                              ; takes 8 from stack
    popa
    mov eax, 0                                              ; return back to C
    leave                     
    ret
1

There are 1 answers

0
Marko Sameh On

haha I'm doing the exact same assignment and stuck on the algorithm however though when running your code it seems to identify "too many arguments" even though only one argument is provided, consider this algorithm when dealing with arguments(don't forget ./ is considered the "first argument" since it is the zeroth argument provided):

  enter 0,0
  pusha
    ; address of 1st argument is on stack at address ebp+12
    ; address of 2nd arg = address of 1st arg + 4
  mov eax, dword [ebp+12]   ;eax = address of 1st arg
  add eax, 4        ;eax = address of 2nd arg
  mov ebx, dword [eax]  ;ebx = 2nd arg, it is pointer to string
  mov eax, 0        ;clear the register
  mov al, [ebx]     ;it moves only 1 byte
  sub eax, '0'      ;now eax contains the numeric value of the firstcharacter of string