2016-08-31 63 views
5
BOOL32 doStuff() { 
    return TRUE; 
} 

gcc 2.95 dla VxWorks 5.x, kompilacja powyższy kod -O0 dla 32-bit x86 generowany po kodzie:GCC generuje niepotrzebne instrukcje?

  doStuff: 
0e9de190: push %ebp 
0e9de191: mov  %esp,%ebp 
308   return TRUE; 
0e9de193: mov  $0x1,%eax 
0e9de198: jmp  0xe9de1a0 <doStuff+16> 
312  { 
0e9de19a: lea  0x0(%esi),%esi 
// The JMP jumps here 
0e9de1a0: mov  %ebp,%esp 
0e9de1a2: pop  %ebp 
0e9de1a3: ret 

Wszystko wygląda normalnie, aż do instrukcji JMP i Lea. Do czego one służą?


Zgaduję, że jest to pewnego rodzaju wyrównanie, ale nie jestem tego pewien.

bym zrobił coś takiego:

  doStuff: 
0e9de190: push %ebp 
0e9de191: mov  %esp,%ebp 
308   return TRUE; 
0e9de193: mov  $0x1,%eax 
0e9de1XX: mov  %ebp,%esp 
0e9de1XX: pop  %ebp 
0e9de1XX: ret 
0e9de1XX: fill with lea 0x0, %esi 
+0

Który z zapisanych kodów został ostatecznie przetłumaczony na zespół wygenerowany powyżej? Powinieneś dołączyć te informacje, aby zwiększyć szanse na uzyskanie pomocy. – ray

+0

Czy kompilowano z optymalizacją? Jaka platforma/system operacyjny? – rubenvb

+0

Dodano infos nadzieję, że to pomaga – maxbit89

Odpowiedz

8

lea 0x0(%esi),%esi jest długa NOP i JMP skacze nad nim. Prawdopodobnie masz starą wersję binutils (zawierającą as), aby przejść do starej wersji gcc.

Tak więc, gdy gcc umieści etykietę w środku funkcji, która w przeciwnym razie nie jest celem rozgałęzienia (z jakiegoś dziwnego powodu, ale jest to -O0, więc nie powinien to być nawet dobry kod), asembler wykonał długi NOP i przeskoczył nad nim.

Normalnie przeskakiwałbyś tylko blok NOP-ów, gdyby było ich dużo, szczególnie jeśli były one jednobajtowymi NOP-ami. To naprawdę głupi kod, więc przestań używać takich chrupiących narzędzi. Możesz spróbować zaktualizować swój asembler (ale nadal używając gcc2.95, jeśli potrzebujesz). Lub sprawdź, czy nie ma to miejsca pod numerem -O2 lub -O3, w takim przypadku nie ma to znaczenia.

Jeśli z jakiegoś powodu musisz nadal używać gcc2.95, to po prostu pamiętaj, że jest starożytny i jest to część kompromisu, którego używasz, aby nadal używać tego, co zmusza do użycia go.

+1

Z -O2 wygląda znacznie lepiej ^^ – maxbit89