用汇编与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#,不再需要交换数据时的临时变量,代码又节省了。
浙公网安备 33010602011771号