На сколько байтов скомпилирована каждая инструкция в сборке x86? - PullRequest
7 голосов
/ 30 марта 2010
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

Ответы [ 5 ]

6 голосов
/ 30 марта 2010

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

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 и рассчитайте для каждой инструкции, префикса и операнда

3 голосов
/ 04 мая 2010

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

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

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

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

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

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

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

1 голос
/ 30 марта 2010

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

0 голосов
/ 24 августа 2014

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

0 голосов
/ 30 марта 2010

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

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

...