【问题标题】:Tower of Hanoi in assembly x86 using arrays使用数组的 x86 大会中的河内塔
【发布时间】:2023-12-18 23:31:01
【问题描述】:

大家好,我正在尝试在 x86 中组装河内塔,但我正在尝试使用数组。所以这段代码从用户那里获取一个数字作为 Linux 中的参数,然后错误检查一堆东西。所以现在我只想制作使用我制作的三个数组(开始,结束,临时)的算法并逐步输出它们。如果有人可以提供帮助,将不胜感激。 `

%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

【问题讨论】:

  • 你到底有什么问题?
  • 使用数组制作河内塔算法。
  • 数组或算法有问题吗?
  • 我想不出一个使用数组的算法。
  • 你能找出解决这个问题的算法吗?

标签: linux assembly x86 nasm towers-of-hanoi


【解决方案1】:

哈哈,我正在做完全相同的分配并坚持使用算法,但是在运行您的代码时,即使只提供了一个参数,它似乎识别出“太多参数”,在处理参数时考虑这个算法(不要' t forget ./ 被认为是“第一个参数”,因为它是提供的第零个参数):

  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

【讨论】: