2016-12-23 4 views
1

Недавно я использовал опасную программу и нашел что-то интересное в разнице между версиями gcc на архитектуре x86-64.Причины и преимущества этого улучшения по версии gcc> = 4.9.0 vs gcc version <4.9?

Примечание:

  1. Неправомерное использование gets является не вопрос здесь.

  2. Если мы заменим gets на любые другие функции, проблема не изменится.


Это исходный код я использую:

#include <stdio.h> 
int main() 
{ 
    char buf[16]; 
    gets(buf); 
    return 0; 
} 

Я использую gcc.godbolt.org разобрать программу с флагом -m32 -fno-stack-protector -z execstack -g.

В разобранном коде, когда gcc с версии> = 4.9.0:

lea  ecx, [esp+4]   # begin of main 
and  esp, -16 
push DWORD PTR [ecx-4]  # push esp 
push ebp 
mov  ebp, esp 
/* between these comment is not related to the question 
push ecx 
sub  esp, 20 
sub  esp, 12 
lea  eax, [ebp-24] 
push eax 
call gets 
add  esp, 16 
mov  eax, 0 
*/ 
mov  ebp, esp    
mov  ecx, DWORD PTR [ebp-4] # ecx = saved esp 
leave 
lea  esp, [ecx-4] 
ret        # end of main 

Но НКУ с версии < 4.9.0 просто:

push ebp      # begin of main 
mov  ebp, esp 
/* between these comment is not related to the question 
and  esp, -16 
sub  esp, 32 
lea  eax, [esp+16] 
mov  DWORD PTR [esp], eax 
call gets 
mov  eax, 0 
*/ 
leave 
ret        # end of main 

Мой вопрос: Что такое cau ses этой разницы на разобранном коде и его преимуществах? Имеет ли это название для этой техники?

+1

Примечание: [НЕ использовать 'gets()', это опасно] (http://stackoverflow.com/q/1694036/2173917). используйте вместо этого '' fgets() '] (https://linux.die.net/man/3/fgets). –

+1

Это результат оптимизации –

+2

Различные конфигурации компилятора. Используйте 'gcc -v' для сравнения конфигураций – LPs

ответ

0

Я не могу точно сказать, без фактических значений:

and  esp, 0xXX    # XX is a number 

, но это выглядит как дополнительный код для выравнивания стека на большее значение, чем ABI требует.

Редактировать: значение -16, которое представляет собой 32-разрядный 0xFFFFFFF0 или 64-разрядный 0xFFFFFFFFFFFFFFF0, так что это действительно выравнивание стека до 16 байтов, что, вероятно, предназначено для использования инструкций SSE. Как уже упоминалось в комментариях, в версии> = 4.9.0 больше кода, потому что он также выравнивает указатель кадра вместо указателя стека.

+0

Прошу прощения, это моя ошибка, чтобы заменить '-16' на' 0xXX'. Очень жаль ! – lzutao

+0

@lzutao Затем это код выравнивания стека. – Olivier

+0

Спасибо. Но у него также есть выравнивание данных с версией gcc <** 4.9.0 ** – lzutao

 Смежные вопросы

  • Нет связанных вопросов^_^