下面有两个相同的汇编代码,编写快速排序。唯一的区别是,在第一个中进行减法,然后将结果与零进行比较,在第二个中,它只是一个比较。出于某种原因,第一段代码实际上排序正确,但第二段没有。我已就此进行了一些研究:cmp
并未改变操作数,而“{1}}不会改变操作数,而”' sub'确实
首先(正确):
##
##
## quick_sort(int *a, int l, int r){
## int i, j, pivot, temp;
## if(l>=r) return;
##
## pivot = a[r];
## i = l;
## j = r;
##
## while(i<j){
## while(i < j && a[i]<pivot) i++;
## while(i < j && a[j]>=pivot) j--;
## temp = a[i];
## a[i] = a[j];
## a[j] = temp;
## }
## a[r] = a[i];
## a[i] = pivot;
##
## quick_sort(a, l, i-1);
## quick_sort(a, i+1, r);
## }
##
.intel_syntax noprefix
.text
.global quick_sort
########################################
# void quick_sort(int *a, int l, int r)
#
# rdi - int *a
# rsi - int l
# rdx - int r
########################################
quick_sort:
enter 0, 0
cmp rsi, rdx
jge end_quick_sort
mov r12, [rdi+rdx*4]
mov r13, rsi # i=l
mov r14, rdx # j=r
partition:
cmp r13, r14
jge end_partition
left_loop:
cmp r13, r14
jge end_left_loop
mov rax, [rdi+r13*4]
sub rax, r12 #this
cdqe #piece
cmp rax, 0 #here
jge end_left_loop
inc r13
jmp left_loop
end_left_loop:
right_loop:
cmp r13, r14
jge end_right_loop
mov rax, [rdi+r14*4]
sub rax, r12
cdqe
cmp rax, 0
jl end_right_loop
dec r14
jmp right_loop
end_right_loop:
mov rax, [rdi + r13*4]
mov r15, [rdi + r14*4]
mov [rdi + r13*4], r15d
mov [rdi + r14*4], eax
jmp partition
end_partition:
mov rax, [rdi + r13*4] # a[r] = a[i]
mov [rdi + rdx*4], eax
mov [rdi + r13*4], r12d # a[i] = pivot
quick_sort_left: # quick_sort(array,l,i-1)
push rdx
push r13
mov rdx, r13
dec rdx
call quick_sort
pop r13
pop rdx
quick_sort_right: # quick_sort(array,i+1,r)
mov rsi, r13
inc rsi
call quick_sort
end_quick_sort:
xor rax, rax
leave
ret
第二(不正确):
.intel_syntax noprefix
.text
.global quick_sort
quick_sort:
enter 0,0
cmp rsi, rdx
jge end_qs
mov r12, [rdi + 4*rdx]
mov r13, rsi
mov r14, rdx
main_while:
cmp r13, r14
jge end_main_while
left_while:
cmp r13, r14
jge end_left_while
mov rax, [rdi + 4*r13]
cmp rax, r12 # changed to just one line (cmp)
jge end_left_while
inc r13
jmp left_while
end_left_while:
right_while:
cmp r13, r14
jge end_right_while
mov rax, [rdi + 4*r14]
cmp rax, r12
jl end_right_while
dec r14
jmp right_while
end_right_while:
mov rax, [rdi + 4*r13]
mov r15, [rdi + 4*r14]
mov [rdi + 4*r13], r15d
mov [rdi + 4*r14], eax
jmp main_while
end_main_while:
mov rax, [rdi + 4*r13]
mov [rdi + 4*rdx], eax
mov [rdi + 4*r13], r12d
qs_left:
push rdx
push r13
mov rdx, r13
dec rdx
call quick_sort
pop r13
pop rdx
qs_right:
mov rsi, r13
inc rsi
call quick_sort
end_qs:
xor rax, rax
leave
ret