Я изучаю ассемблерный код, сгенерированный GCC. Но я не понимаю:
movl $0x2d, 0x4(%esp)
Во втором операнде, что делает 0x4
обозначает? адрес смещения? И что использование регистра EAX?
movl $0x2d, 0x4(%esp)
означает взять текущее значение указателя стека (%esp
), прибавить 4 (0x4
), затем сохранить длинное (32-битное) значение 0x2d
в это место.
Регистр eax
является одним из 32-битных регистров общего назначения. Архитектура x86 определяет следующие 32-битные регистры:
eax Accumulator Register
ebx Base Register
ecx Counter Register
edx Data Register
esi Source Index
edi Destination Index
ebp Base Pointer
esp Stack Pointer
а названия и назначение некоторых из них восходят к временам Intel 8080.
Эта страница дает хороший обзор регистров типа Intel. К первым четырем из приведенного выше списка также можно обращаться как к 16-битному или двум 8-битным значениям. Например:
3322222222221111111111
10987654321098765432109876543210
<- eax ->
<- ax ->
<- ah -><- al ->
Регистры указателей и индексов не позволяют использовать 8-битные части, но вы можете иметь, например, 16-битный bp
.
0x4 (% esp)
означает * (% esp + 4)
, где *
означает разыменование.
Оператор означает сохранение непосредственного значения 0x2d в некоторой локальной переменной, занимающей 4-е смещение в стеке.
(Показанный вами код имеет синтаксис AT&T. В синтаксисе Intel это будет mov [esp, 4], 2dh
)
Вы обращаетесь к чему-то на четыре байта удаленному от места, где находится указатель стека. В GCC это означает параметр (я думаю -- положительное смещение это параметры, а отрицательное -- локальные переменные, если я правильно помню). Другими словами, вы записываете в параметр значение 0x2D. Если бы вы дали больше контекста, я бы мог сказать, что происходит во всей процедуре.
0x4
во втором операнде - это смещение от значения регистра в паренсах. EAX
- это регистр общего назначения, используемый для кодирования на ассемблере (вычисления, хранение временных значений и т.д.) Формально он называется "регистр-аккумулятор", но это больше исторический момент, чем актуальный.
Вы можете прочитать эту страницу об архитектуре x86. Наиболее релевантными для вашего вопроса являются разделы Режимы адресации и Регистры общего назначения
Операнды ассемблера GCC следуют за байтом (b), словом (w), длиной (l) и так далее, например:
movb movw movl
Регистры имеют префикс со знаком процента (%).
Константы имеют префикс со знаком доллара ($).
В примере выше в вашем вопросе это означает 4-е смещение от указателя стека (esp).
Надеюсь, это поможет, С наилучшими пожеланиями, Том.