В какое количество byes каждая инструкция компилируется в x86 блоке?

0x004012d0 <main+0>:    push   %ebp
0x004012d1 <main+1>:    mov    %esp,%ebp
0x004012d3 <main+3>:    sub    $0x28,%esp

Если адрес не доступен, мы можем вычислить его сами?

Я подразумеваю, что у нас только есть это:

push   %ebp
mov    %esp,%ebp
sub    $0x28,%esp
7
задан Ciro Santilli 新疆改造中心法轮功六四事件 9 November 2015 в 17:20
поделиться

4 ответа

Первая инструкция находится в [main + 0], а вторая находится по адресу [main + 1], поэтому длина первой инструкции составляет 1 байт. Третья инструкция находится в [main + 3], поэтому вторая инструкция занимает два байта. Вы не можете сказать из листинга, какова длина третьей инструкции, поскольку она не показывает адрес 4. инструкции.

1
ответ дан 7 December 2019 в 01:19
поделиться

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

Например, вот 32-разрядный ассемблер 80x86 открытый исходный код ( OllyDbg v1.10 ).

0
ответ дан 7 December 2019 в 01:19
поделиться

количество байтов - это разница адресов между соседними инструкциями:

0x004012d0 <main+0>:    push   %ebp ;1 byte
0x004012d1 <main+1>:    mov    %esp,%ebp ;2 bytes
0x004012d3 <main+3>:    sub    $0x28,%esp

если у вас есть только текст, перейдите сюда: http://www.swansontec.com/sintel.html и здесь: http://faydoc.tripod.com/cpu/conventions.htm и рассчитайте для каждой инструкции, префикса и операнда

6
ответ дан 7 December 2019 в 01:19
поделиться

Вы не можете обязательно определить размер инструкции по мнемонике. Вот несколько особых случаев:

  • если вы находитесь в 16-битном сегменте, mov eax, 0 требует префикса 0x66 , а в 32-битном сегменте - нет. т. Вам нужно знать размер сегмента.

  • в 32-битном или 16-битном режиме вы можете закодировать добавить eax, 1 как 0x40 ( inc eax ) или 0x83 0xc0 0x01 ( добавить eax, 1 ). То есть есть некоторые мнемоники, которые можно закодировать более чем одним способом.

  • Операнд памяти [eax] может кодировать eax либо как основание, либо как индекс. Если это индекс, у вас будет дополнительный байт SIB после MOD / RM.

  • в 64-битном режиме вы можете использовать префикс REX 0x4x для кодирования регистров r8 - r15 . Однако вы можете использовать 0x40 как своего рода нулевой байт REX, который добавит к вашей инструкции еще один байт.

  • могут использоваться переопределения сегмента, даже если явный сегмент такой же, как неявный.

Есть много других способов кодировать инструкцию, используя большее или меньшее количество байтов. Хороший ассемблер, вероятно, всегда должен использовать самый короткий, но это определенно не требуется архитектурой.Хорошо то, что если вы изучите том 2 Руководства разработчика программного обеспечения Intel IA-32, вы сможете решить его самостоятельно.

3
ответ дан 7 December 2019 в 01:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: