1

我一直在研究这个汇编程序来对数字列表进行排序,似乎我正在遵循 shell 排序的逻辑,但是当我运行它时,它会连续运行,因此在我的排序中存在一个问题,我正在制作一个错误?我很确定以 36 为基数的整数宏可以工作,但我需要让排序工作,从头开始重写并遇到同样的问题。最初我使用的是整个 300 列表,我通过循环获得了大约 6 次运行的正确值,但我在某个时候遇到了问题,决定将 lst 缩短为 5 并重写。

        ; -----
        ; Shell Sort

        ;   h = 1;
        ;       while ( (h*3+1) < a.length) {
        ;       h = 3 * h + 1;
        ;   }

        ;       while( h > 0 ) {
        ;           for (i = h-1; i < a.length; i++) {
        ;               tmp = a[i];
        ;               j = i;
        ;               for( j = i; (j >= h) && (a[j-h] > B); j -= h) {
        ;                   a[j] = a[j-h];
        ;               }
        ;               a[j] = tmp;
        ;           }
        ;           h = h / 3;
        ;       }

        ; **********************************************************************************
        ;  Macro, "int2b36", to convert a signed base-10 integer into an
        ;  ASCII string representing the base-36 value.  The macro stores
        ;  the result into an ASCII string (byte-size, right justified,
        ;  blank filled, NULL terminated).  Each integer is a doubleword value.
        ;  Assumes valid/correct data.  As such, no error checking is performed.

        ; -----
        ;  Arguments
        ;   %1 -> integer number
        ;   %2 -> string address

        %macro  int2b36 2


        ;   YOUR CODE GOES HERE
        push    rax
            push    rbx
            push    rcx
            push    rdx
            push    rsi
            push    rdi


        ;   YOUR CODE GOES HERE
            mov r8, 0
            mov r9, 0
            mov r10, 0
            mov r11, 0
            mov r12, 0
            mov r13, 0
            mov r14, 0
            mov rbx, 0
            mov rbx, %2
            mov eax, 0
            mov eax, dword[%1]
            %%divDec:
            cmp dword[%1],0
            je %%divDone
            div dword[decto36]
            mov dword[%1],eax

            push rdx
            inc r14
            mov rdx, 0
            jmp %%divDec

            %%divDone:
            mov r13, MAX_STR_SIZE
            sub r13, r14
            sub r13, 1
            %%spacefill:
            mov al,0x20
            mov [rbx+rsi], al
            dec r13
            inc rsi
            cmp r13,0
            jne %%spacefill
            %%numFill:
            pop r8
            cmp r8, 9
            jbe %%lsthan9
            sub r8b, 10
            add r8b,"A"
            mov [rbx+rsi],r8b
            inc rsi
            mov r8, 0
            dec r14
            cmp r14,0
            je %%finishCalc
            jmp %%numFill

            %%lsthan9:
            add r8b, "0"
            mov [rbx+rsi],r8b
            inc rsi
            dec r14
            cmp r14, 0
            mov r8, 0
            je %%finishCalc
            jmp %%numFill;

            %%finishCalc:


            pop rdi
            pop rsi
            pop rdx
            pop rcx
            pop rbx
            pop rax


        %endmacro

        ; --------------------------------------------------------------
        ;  Simple macro to display a string.
        ;   Call:   printString  <stringAddress>

        ;   Arguments:
        ;       %1 -> <string>, string address

        ;  Count characters (excluding NULL).
        ;  Display string starting at address <string>

        %macro  printString 1
            push    rax         ; save altered registers
            push    rdi
            push    rsi
            push    rdx
            push    rcx

            mov rdx, 0
            mov rdi, %1
        %%countLoop:
            cmp byte [rdi], NULL
            je  %%countLoopDone
            inc rdi
            inc rdx
            jmp %%countLoop
        %%countLoopDone:

            mov rax, SYS_write      ; system call for write (SYS_write)
            mov rdi, STDOUT     ; standard output
            mov rsi, %1         ; address of the string
            syscall             ; call the kernel

            pop rcx         ; restore registers to original values
            pop rdx
            pop rsi
            pop rdi
            pop rax
        %endmacro

        ; ---------------------------------------------

        section .data

        ; -----
        ;  Define constants.

        TRUE        equ 1
        FALSE       equ 0

        EXIT_SUCCESS    equ 0           ; Successful operation

        STDIN       equ 0           ; standard input
        STDOUT      equ 1           ; standard output
        STDERR      equ 2           ; standard error

        SYS_read    equ 0           ; system call code for read
        SYS_write   equ 1           ; system call code for write
        SYS_open    equ 2           ; system call code for file open
        SYS_close   equ 3           ; system call code for file close
        SYS_fork    equ 57          ; system call code for fork
        SYS_exit    equ 60          ; system call code for terminate
        SYS_creat   equ 85          ; system call code for file open/create
        SYS_time    equ 201         ; system call code for get time

        LF      equ 10
        NULL        equ 0
        ESC     equ 27

        ; -----
        ;  Provided data

        lst dd  1113, 1232, 2146, 1376, 5120;, 2356,  164, 4565, 155, 3157
            ;dd  759, 326,  171,  147, 5628, 7527, 7569,  177, 6785, 3514
            ;dd 1001,  128, 1133, 1105,  327,  101,  115, 1108,    1,  115
            ;dd 1227, 1226, 5129,  117,  107,  105,  109,  999,  150,  414
            ;dd  107, 6103,  245, 6440, 1465, 2311,  254, 4528, 1913, 6722
            ;dd 1149,  126, 5671, 4647,  628,  327, 2390,  177, 8275,  614
            ;dd 3121,  415,  615,  122, 7217,    1,  410, 1129,  812, 2134
            ;dd  221, 2234,  151,  432,  114, 1629,  114,  522, 2413,  131
            ;dd 5639,  126, 1162,  441,  127,  877,  199,  679, 1101, 3414
            ;dd 2101,  133, 1133, 2450,  532, 8619,  115, 1618, 9999,  115
            ;dd  219, 3116,  612,  217,  127, 6787, 4569,  679,  675, 4314
            ;dd 1104,  825, 1184, 2143, 1176,  134, 4626,  100, 4566,  346
            ;dd 1214, 6786,  617,  183,  512, 7881, 8320, 3467,  559, 1190
            ;dd  103,  112,    1, 2186,  191,   86,  134, 1125, 5675,  476
            ;dd  100,    1, 1146,  100,  101,    1, 5616, 5662, 6328, 2342
            ;dd 2137, 2113,  647,  114,  115, 6571, 7624,  128,  113, 3112
            ;dd  724,  316, 1217, 2183, 4352,  121,  320, 4540, 5679,  190
            ;dd 9125,  116, 1122,  117,  127, 5677,  101, 3727, 6512, 3184
            ;dd 1897, 6374,  190, 1667, 1224, 7123,  116,  126, 6784, 2329
            ;dd  104,  124, 1112,  187,  176, 7534, 2126, 6112,  156,  103
            ;dd 1153,  172, 1146, 2176,  170,  156,  164,  165,  155, 5156
            ;dd  894, 6325,  100,  143,  276, 5634, 7526,  413, 7686,  563
            ;dd  511,  383, 1133, 2150,  825, 5721,  615, 4568, 7813, 1231
            ;dd  999,  146,  162,  147,  157,  167,  169,  177,  175,  144
            ;dd 5527, 1344, 1130, 2172,  224, 7525,  100,    1,  100, 1134   
            ;dd  181,  155, 1145,  132,  167,  185,  150,  149,  182,  434
            ;dd  581,  625, 6315,    1,  617,  855, 6737,  129, 4512,    1
            ;dd  177,  164,  160, 1172,  184,  175,  166, 6762,  158, 4572
            ;dd 6561,  283, 1133, 1150,  135, 5631, 8185,  178, 1197,  185
            ;dd  649, 6366, 1162,  167,  167,  177,  169, 1177,  175, 1169

        ;len    dd  300
        len     dd  5

        min dd  0
        med dd  0
        max dd  0
        sum dd  0
        avg dd  0

        ; -----
        ;  Misc. data definitions (if any).

        h       dd  0
        i       dd  0
        j       dd  0
        tmp     dd  0
        dSix        dd  6
        dTwo        dd  2
        dThree      dd  3
        decto36     dd  36


        ; -----
        ;  Provided string definitions.

        MAX_STR_SIZE    equ 12

        newLine     db  LF, NULL

        hdr     db  LF, "---------------------------"
                db  "---------------------------"
                db  LF, ESC, "[1m", "---------------", ESC, "[0m"
                db  LF, "Shell Sort", LF, LF, NULL

        hdrMin      db  "Minimum:  ", NULL
        hdrMax      db  "Maximum:  ", NULL
        hdrMed      db  "Median:   ", NULL
        hdrSum      db  "Sum:      ", NULL
        hdrAve      db  "Average:  ", NULL

        ; ---------------------------------------------

        section .bss

        tmpString   resb    MAX_STR_SIZE

        ; ---------------------------------------------

        section .text
        global  _start
        _start:

        ; ******************************
        ;  Shell Sort.

            mov eax, 0      ;set eax to 0
            mov esi, 4      ;set esi to 4
            inc eax         ; inc eax to 1
            mov dword[h],eax ; set h to 1
            mov ebx, 3          ;put 3 into ebx
            mov ecx, dword[len]  ;mov length into ecx
            firstWhile:
            mul ebx             ; multiply eax by 3
            inc eax             ; add 1 to eax/whixh is h
            cmp eax, ecx        ;compare h*3+1 to length
            jb changeH          ; if < length jmp to changeH
            jmp secondWhile     ;else jmp to secondWhile

            changeH:
            mov dword[h], eax  ;move eax into h
            mov r10d, dword[h]  ;save h in r10d for later use
            jmp firstWhile      ;back to firstWhile

            secondWhile:
            mov eax, dword[h]           ;reset eax to h
            cmp dword[h],0      ;compare h to 0
            ja firstFor         ;if > 0 jmp to firstFor
            jmp doneFinish      ;else jmp to doneFinish

            firstFor:
            dec eax             ;subtract 1 from eax
            mov dword[i], eax   ;move eax into i
            mov r12d, dword[i]  ;move i into r12d for later use
            firstFor1:
            cmp r12d, ecx       ;compare r12d which is i to ecx which is length
            jb firstForCalc     ;if i < length jmp to firstForCalc
            jmp divAfterFors    ;else jump to divAfterFors

            firstForCalc:
            mov eax, r12d       ;move i into eax to use multiply
            mul esi             ;multiply eax which is now i by offset esi/4    
            mov r8d, dword[lst+eax] ;take lst[i] and put into r8
            mov dword[tmp], r8d     ;move r8d into tmp
            mov dword[j], r12d      ;move i into j
            mov r14d, dword[j]      ;save j in r14d for later use
            mov r11d, dword[j]      ;save j in r11d, use in nested for calc

            secondFor:
            mov r9d,dword[h]    ;move h into r9d
            cmp dword[j], r9d   ;compare j to h
            jb firstForCalcTwo  ;if j<h skip nested for to 2nd calc of outer for
            jmp secondForTwo    ;else jmp to second condition of nested for

            firstForCalcTwo:
            mov eax, dword[j]       ;move j into eax
            mul esi                 ; multiply by offset esi/4
            mov dword[lst+eax], r8d ;move temp into lst[j]
            inc r12d                ; i++
            jmp firstFor1           ;jmp to i<length condition in outer for


            secondForTwo:
            sub r14d,r10d      ;j-h 
            mov eax, r14d       ;move j-h into eax
            mul esi             ;multiply by esi offset 4
            mov r13d, dword[lst+eax] ;move lst[j-h] into r13 to check value debbug
            cmp dword[lst+eax], r8d  ;compare lst[j-h] to tmp
            ja secondForCalc    ;if > than jmp to nested for loop calculations
            jmp firstForCalcTwo ;else skip nested for, jmp to 2nd calc of outer for



            secondForCalc:
            mov eax, r11d ;move j into eax to multiply
            mul esi                 ;multiply by offset esi/4
            mov dword[lst+eax], r8d ;move tmp into lst[j]
            mov dword[j],r14d       ;j-h into j
            jmp secondFor







            divAfterFors:
            mov eax, r10d   ;move h into eax
            div ebx         ;divide by 3
            mov dword[h], eax ;move result into h
            jmp secondWhile

            doneFinish:



        ; ******************************
        ;  Display results to screen in hex.

            printString hdr

            printString hdrMin
            int2b36     min, tmpString
            printString tmpString
            printString newLine

            printString hdrMax
            int2b36     max, tmpString
            printString tmpString
            printString newLine

            printString hdrMed
            int2b36     med, tmpString
            printString tmpString
            printString newLine

            printString hdrSum
            int2b36     sum, tmpString
            printString tmpString
            printString newLine

            printString hdrAve
            int2b36     avg, tmpString
            printString tmpString
            printString newLine
            printString newLine

        ; ******************************
        ;  Done, terminate program.

        last:
            mov rax, SYS_exit
            mov rbx, EXIT_SUCCESS
            syscall
4

0 回答 0