2010-10-24 17 views
8

Mam następujący kod języka asemblerowego, który muszę przekonwertować na C. Jestem zdezorientowany na kilku liniach kodu.Język kompilacji do C

Rozumiem, że jest to pętla for. Dodałem moje komentarze do każdej linii.

myślę pętla for idzie tak

for (int i = 1; i > 0; i << what?) { 
    //Calculate result 
} 

Jaki jest stan test? I jak to zmienić?

Co robi zmienna "n", patrząc na kod zespołu?

Jest Intel x86 więc format jest movl = source, dest

movl 8(%ebp), %esi  //Get x 
    movl 12(%ebp), %ebx //Get n 
    movl $-1, %edi   //This should be result 
    movl $1, %edx   //The i of the loop 
.L2: 
    movl %edx, %eax 
    andl %esi, %eax 
    xorl %eax, %edi  //result = result^(i & x) 
    movl %ebx, %ecx  //Why do we do this? As we never use $%ebx or %ecx again 
    sall %cl, %edx   //Where did %cl come from? 
    testl %edx, %edx  //Tests if i != what? - condition of the for loop 
    jne .L2    //Loop again 
    movl %edi, %eax  //Otherwise return result. 
+1

test% edx, edx% sprawdza, czy edx ma wartość 0., a następnie jne - przeskocz jeśli nie jest zero. –

+0

Które linie są zagubione? W C, pętla for jest dla (;;) {} –

+0

Dlaczego konwertujesz starsze asmy na C? –

Odpowiedz

14

sall %cl, %edx przesunięcia% EDX pozostawione przez %cl bitów. (%cl, dla porównania, jest niskim bajtem %ecx.) Kolejne testl sprawdza, czy to przesunięcie wyzerowało% edx.

Nazywa się to jne, ponieważ jest często używany w kontekście porównań, które w ASM często są po prostu odejmowaniem. Flagi byłyby ustawione na podstawie różnicy; ZF byłby ustawiony, jeśli pozycje są równe (od x - x == 0). Nazywa się również jnz w składni Intela; nie jestem pewien, czy GNU na to pozwala.

Łącznie trzy instrukcje tłumaczą się na i <<= n; if (i != 0) goto L2;. To plus etykieta wydaje się tworzyć pętlę for.

for (i = 1; i != 0; i <<= n) { result ^= i & x; } 

Albo, bardziej poprawnie (ale osiągając ten sam cel), a do ... while loop.

+0

Dziękujemy! To było bardzo pomocne. – Catie