我一直在研究这个汇编程序来对数字列表进行排序,似乎我正在遵循 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