Сборка: слишком много места в стеке для локальных переменных - PullRequest
0 голосов
/ 27 декабря 2011

В настоящее время я пытаюсь понять некоторый ассемблерный код достаточно хорошо, чтобы восстановить код C из него. Хотя я почти закончил с этим, есть одна вещь о локальных переменных, которая озадачивает меня.

Доступ к локальным переменным осуществляется с помощью esp Base Pointer и вычитает их смещения, например, -0xc(%ebp) ссылается на локальную переменную. Чтобы интерпретировать это в C-код, мне нужно знать, какого размера эти переменные (по крайней мере, если они являются массивами). Это можно сделать, рассчитав разницу между смещениями других переменных. Если существуют локальные переменные -0xc(%ebp) и -0x8(%ebp), мы знаем, что -0xc(%ebp), скорее всего, имеет длину 4 байта. Но как насчет -0x8(%ebp), если в дизассемблированном виде нет другого доступа к какой-либо локальной переменной? Можем ли мы предположить, что он должен иметь размер 8 байт? Я так не думаю ...

Моя проблема заключается в следующем: кажется, что компилятор выделил больше места для локальных переменных, чем необходимо. Позвольте мне показать вам этот простой пример: функция ошибок, разобранная с помощью gdb.

push   %ebp              
mov    %esp,%ebp      
sub    $0x8,%esp               // 0x8 = 8 byte for local variables
mov    0x8(%ebp),%eax          // errormsg is a function argument  
mov    %eax,(%esp)             
call   0x80485cc <perror@plt>  // perror(errormsg)
movl   $0x1,(%esp)                 
call   0x804866c <exit@plt>    // exit(1)

Эта функция, очевидно, не имеет доступа ни к каким локальным переменным, поэтому мы можем подозревать, что их нет. Но все же есть 8 байтов, выделенных для локальных переменных, не так ли?

Это не единственный пример, который я видел, где есть место, выделенное для переменных, которые не нужны. Думаю, я что-то упускаю, но пока я так делаю, я не могу узнать о размерах всех переменных, которые мне нужны для написания кода на Си.

Есть предложения?

Заранее спасибо!

1 Ответ

3 голосов
/ 27 декабря 2011

Инструкция mov %eax,(%esp) здесь используется вместо push. Итак, хотя локальные переменные не используются, это не значит, что зарезервированное пространство стека потрачено впустую. Конечно, похоже, что функция резервирует 8 байтов для локальных переменных, когда ей нужно только зарезервировать 4, но, возможно, это соглашение, используемое компилятором: всегда резервируйте стек в блоках по 8 байтов. В некотором смысле имеет смысл сохранять стек выровненным по qword.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...