Определение количества байтов, разделяющих esp и сохраненный адрес возврата в стеке программы

Я не могу найти ответ. Из того, что я читал,% ebp имеет 32 бита, перемещая% esp в% ebp, у вас все равно будет 32 бита, затем вычтите 70 из 32, а остальное я не понимаю. Я новичок в этом, поэтому я не очень разбираюсь. Пожалуйста, дайте подробное объяснение. Спасибо!

Ниже приведен вопрос, с которым у меня возникли проблемы.

Сколько байтов отделяют esp от сохраненного адреса возврата в стеке программы в конце этой последовательности инструкций? Предположим, что мы вызвали эту функцию, используя стандартные 32-разрядные соглашения о вызовах x86.

804847c functioname:
804847c: push %ebp
804847d: mov %esp,%ebp
804847f: sub $0x70,%esp
8048482: movl $0x0,0x4(%esp)
804848a: movl $0x8048580,(%esp)

person Kahrte_blanche    schedule 15.08.2017    source источник
comment
Значение $0x70 в этой инструкции sub $0x70,%esp расширено знаком до 32 бит, поэтому оно также имеет 32 бита, как и esp и ebp. (хотя внутренне значение 0x70 закодировано в инструкциях только в 8 битах, но это не то, как оно используется, это только оптимизация хранения в данном конкретном случае). Количество используемых битов ограничивает количество различных значений, которые могут быть закодированы в этих битах, т.е. 8 битов можно интерпретировать как значения от 0 до 255, или от -128 до +127, или как восемь 1-битных флагов (вкл. / Выкл.). В вашем вопросе это не имеет большого значения, так как все задействованные значения - 32b.   -  person Ped7g    schedule 15.08.2017


Ответы (1)


sub $0x70,%esp: зарезервировать 0x70 байт в стеке.

movl $0x0,0x4(%esp): введите нулевое 32-битное значение в качестве аргумента.

movl $0x8048580,(%esp): Разместите адрес. Следующий подхват прыгнет на него.

По стандартному соглашению о вызовах с именем cdecl в стек помещаются аргументы, за которыми следует адрес, по которому вызываемый объект должен вернуться.

person yacc    schedule 15.08.2017
comment
Это не кажется правильным. ESP уменьшен на 0x70 (112 байт). После инструкции sub временная копия EBP находится в ESP + 0x70, а адрес возврата находится в ESP + 0x74. 0x04 (% esp) и (% esp) фактически указывают на область локальной переменной, которая была создана в стеке с помощью инструкции sub $0x70,%esp - person Michael Petch; 15.08.2017
comment
На мой взгляд, ответ на актуальный вопрос заключается в том, что разница между ESP и адресом возврата составляет 0x70 + 0x04 (4 байта для отправки EBP). Это 116 десятичных или 0x74 шестнадцатеричных. - person Michael Petch; 15.08.2017
comment
Следует отметить, что movl инструкции - мы не знаем, для чего они предназначены. Их фактическое включение в вопрос фактически не меняет разницы между ESP и обратным адресом. На самом деле они просто отвлекающий маневр. Это пахнет домашним заданием, поэтому, вероятно, преподаватель надеялся запутать студентов двумя последними инструкциями. - person Michael Petch; 15.08.2017
comment
@MichaelPetch Не могли бы вы подробно объяснить мне, как вы пришли к этому ответу? например, почему использовались только sub $ 0x70,% esp и movl $ 0x0,0x4 (% esp)? почему другие не рассчитывались? Заранее благодарю вас, я очень ценю ваш вклад. - person Kahrte_blanche; 15.08.2017
comment
Когда функция functioname вызывается, инструкция call помещает адрес возврата в стек. После передачи вызова в functioname ESP указывает на адрес возврата в верхней части стека. push %ebp уменьшает ESP на 4 и помещает туда копию EBP. Следующая инструкция, изменяющая ESP, - sub $0x70,%esp. Это вычитает 0x70 (112) из ​​ESP. Две movl инструкции вообще не изменяют ESP, поэтому их можно игнорировать. Итак, когда все инструкции выполняются, ESP составляет 0x70 + 0x04 = 0x74 байта от адреса возврата - person Michael Petch; 15.08.2017
comment
0x74 - шестнадцатеричное число, представляющее десятичное значение 116 - person Michael Petch; 15.08.2017