用汇编与C实现冒泡排序以及一点思考

汇编实现(AT&T语法):

.section .data

values:

	.int 33, 25, 67, 10, 1

.section .text

.global _start

_start:

	nop

	movl $values, %esi

	movl $4, %ecx

	movl $4, %ebx

loop:

	movl (%esi), %eax

	cmp %eax, 4(%esi)

	jge skip

	xchg %eax, 4(%esi)

	movl %eax, (%esi)

skip:

	add $4, %esi

	dec %ebx

	jnz loop

	dec %ecx

	jz end

	movl $values, %esi

	movl %ecx, %ebx

	jmp loop

end:

	movl $1, %eax

	movl $0, %ebx

	int $0x80

	

C 实现:

#include 
 
   
    
  

#include 
  
    
      void PrintValues(int *values, int count) { if (NULL == values || 0 >= count) return; for (int i = 0; i < count; ++i) { printf("%d,", *(values+i)); } printf("/n"); } int main(int argc, char** argv) { int values[] = {33, 25, 67, 10, 1}; int count = sizeof(values) / sizeof(*values); PrintValues(values, count); for (int outer = 0; outer < count-1; ++outer) { for (int inner = 0; inner < count-1-outer; ++inner) { if (*(values+inner) > *(values+inner+1)) { int temp = *(values+inner); *(values+inner) = *(values+inner+1); *(values+inner+1) = temp; } else { continue; } } } PrintValues(values, count); getchar(); return 0; } 
    
 
   
C 实现的反汇编:
int main(int argc, char** argv)

{

 push        ebp  

 mov         ebp,esp  

 sub         esp,110h  

 push        ebx  

 push        esi  

 push        edi  

 lea         edi,[ebp-110h]  

 mov         ecx,44h  

 mov         eax,0CCCCCCCCh  

 rep stos    dword ptr es:[edi]  

 mov         eax,dword ptr [___security_cookie (257000h)]  

 xor         eax,ebp  

 mov         dword ptr [ebp-4],eax  

	int values[] = {33, 25, 67, 10, 1};

 mov         dword ptr [ebp-1Ch],21h  

 mov         dword ptr [ebp-18h],19h  

 mov         dword ptr [ebp-14h],43h  

 mov         dword ptr [ebp-10h],0Ah  

 mov         dword ptr [ebp-0Ch],1  



	int count = sizeof(values) / sizeof(*values);

 mov         dword ptr [ebp-28h],5  



	PrintValues(values, count);

 mov         eax,dword ptr [ebp-28h]  

 push        eax  

 lea         ecx,[ebp-1Ch]  

 push        ecx  

 call        PrintValues (2511BDh)  

 add         esp,8  



	for (int outer = 0; outer < count-1; ++outer)

 mov         dword ptr [outer],0  

 jmp         main+74h (253604h)  

 mov         eax,dword ptr [outer]  

 add         eax,1  

 mov         dword ptr [outer],eax  

 mov         eax,dword ptr [ebp-28h]  

 sub         eax,1  

 cmp         dword ptr [outer],eax  

 jge         main+0D9h (253669h)  

	{

		for (int inner = 0; inner < count-1-outer; ++inner)

 mov         dword ptr [inner],0  

 jmp         main+91h (253621h)  

 mov         eax,dword ptr [inner]  

 add         eax,1  

 mov         dword ptr [inner],eax  

 mov         eax,dword ptr [ebp-28h]  

 sub         eax,1  

 sub         eax,dword ptr [outer]  

 cmp         dword ptr [inner],eax  

 jge         main+0D7h (253667h)  

		{

			if (*(values+inner) > *(values+inner+1))

 mov         eax,dword ptr [inner]  

 mov         ecx,dword ptr [inner]  

 mov         edx,dword ptr [ebp+eax*4-1Ch]  

 cmp         edx,dword ptr [ebp+ecx*4-18h]  

 jle         main+0D3h (253663h)  

			{

				int temp = *(values+inner);

 mov         eax,dword ptr [inner]  

 mov         ecx,dword ptr [ebp+eax*4-1Ch]  

 mov         dword ptr [temp],ecx  

				*(values+inner) = *(values+inner+1);

 mov         eax,dword ptr [inner]  

 mov         ecx,dword ptr [inner]  

 mov         edx,dword ptr [ebp+ecx*4-18h]  

 mov         dword ptr [ebp+eax*4-1Ch],edx  

				*(values+inner+1) = temp; 

 mov         eax,dword ptr [inner]  

 mov         ecx,dword ptr [temp]  

 mov         dword ptr [ebp+eax*4-18h],ecx  

			}

			else 

 jmp         main+0D5h (253665h)  

			{

				continue;

 jmp         main+88h (253618h)  

			}

		}

 jmp         main+88h (253618h)  

	}

 jmp         main+6Bh (2535FBh)  



	PrintValues(values, count);

 mov         eax,dword ptr [ebp-28h]  

 push        eax  

 lea         ecx,[ebp-1Ch]  

 push        ecx  

 call        PrintValues (2511BDh)  

 add         esp,8  



	getchar();

 mov         esi,esp  

 call        dword ptr [__imp__getchar (2582B0h)]  

 cmp         esi,esp  

 call        @ILT+295(__RTC_CheckEsp) (25112Ch)  



	return 0;

 xor         eax,eax  

}

在用 C 实现时,思考的核心是:如何控制循环,并在正确的时候交换数据。

在用汇编实现时,思考的核心是:如何分配寄存器,如何具体控制循环(loop 与 skip)。

在用汇编时,我先是思考好程序的流程:loop 与 skip,然后建立好对应的结构,再往结构中填写代码,然后控制好程序的执行流程。

汇编比 C 需要思考更多的问题,对程序员的要求也相对高点,C 不需要思考的问题,汇编都需要思考。在用 C# 与 Java 实现冒泡排序时,相对于C,不再需要思考指针操作相关的问题了。当用 Python 等动态语言实现这个算法时,相对于 Java 与 C#,不再需要交换数据时的临时变量,代码又节省了。

你可能感兴趣的:(冒泡排序)