Стек вызовов x86 с сохранением одного байта - PullRequest
2 голосов
/ 26 июля 2011

В настоящее время я изучаю сборку x86 с "Руководством по языку ассемблера в Linux", и на странице 241 написано, что в стек сохраняются только 16-битные или 32-битные слова, но так ли это? Я имею в виду, что в C массив символов состоит из отдельных байтов, и они сохраняются в стеке, поскольку C состоит из функций, которые используют стек вызовов, верно? Так что я не так делаю?

Ответы [ 2 ]

5 голосов
/ 26 июля 2011

Четные байты дополняются нулями и преобразуются в 16-битные или 32-битные слова перед тем, как их толкнуть.

Рассматривает стек как стопку пластин определенного размера (16 или 32).Есть ли способ, которым вы можете толкнуть половину размера пластины .. Нет?Даже если вы хотите выдвинуть половину размера, вы должны дополнить его, чтобы сделать пластину полного размера, а затем нажать ее.

2 голосов
/ 26 июля 2011

Это верно для push инструкций, но это не единственный способ использовать стек. В x86 также есть регистр esp для хранения указателя на текущую позицию стека.

Аргументы функции помещаются в стек, если вы проверите некоторые разборки, вы увидите, как компилятор их туда выводит. В обычном соглашении о вызовах для x86 char аргументы занимают 4 байта каждый. Массивы не могут быть переданы по значению, поэтому не возникает вопроса о том, как массив символов будет сохранен, если они смогут.

Автоматические переменные также занимают стек, но элементы массива не сохраняются в стеке по отдельности с помощью «push». Обычно функция освобождает место для всех своих автоматических переменных в начале - ищите инструкцию «sub», включающую «esp». Тогда начало массива находится с известным смещением от esp, как любая автоматическая переменная, и компилятор будет использовать это смещение для генерации доступа к массиву. Нет необходимости в заполнении элементов, хотя после конца массива могут быть некоторые, чтобы правильно выровнять указатель стека.

...