Это ошибка ассемблера? связанная инструкция - PullRequest
0 голосов
/ 04 сентября 2018

По поводу bytepattern 622c24, есть 2 вида дел.


Первый случай: objdump - as пара.

  1. objdump разбирает 622c24 на: bound %ebp,(%esp)
  2. linux as собирается bound %ebp,(%esp) в: 622c24


Второй случай: библиотека Capstone - keystone пара.

  1. Capstone разбирает 622c24 на: bound (%esp), %ebp

  2. Keystone собирает bound (%esp), %ebp в: 622c24


Как вы можете видеть выше, положение источника и назначения меняется на противоположное.

  • objdump: bound %ebp,(%esp)
  • Замковый камень: bound (%esp), %ebp



В соответствии с синтаксисом AT & T, BOUND r32, m32 является правильным.
Следовательно, это означает, что пара Capstone-keystone является правильной.

Q. Итак, objdump - as есть проблема с разборкой bound инструкции?
Это ошибка binutils?

1 Ответ

0 голосов
/ 04 сентября 2018

Да, это, вероятно, ошибка проектирования в синтаксисе AT & T. Обычно они следуют схеме обращения операндов из синтаксиса Intel и переименования мнемоники знака / нулевого расширения (cdq => cltq, movsx eax, byte[mem] => movsbl). Отклонения от этого можно считать конструктивными ошибками.

Но не ошибки реализации, если старые версии не были другими. Это действительно (но неприятно), когда AT & T просто делает все, что хочет, и устанавливает свои собственные правила для разных инструкций. Это может быть еще один случай совместимости с оригинальным ассемблером Unixware. (см. ниже).


Инструкция bound не записывает ни один из своих входных операндов , поэтому ни один из них на самом деле не является пунктом назначения. И в отличие от cmp, порядок операндов не имеет никакого значения. Он просто проверяет регистр по верхним / нижним границам и вызывает исключение #BR, если оно выходит за пределы.

Для него есть только один код операции, для которого требуются операнды регистр + память (в полях ModR / M r и r/m.


objdump -d перечисляет операнд регистра первым в синтаксисе AT & T и Intel.

Я собрал db 0x62, 0x2c, 0x24 с NASM и связал его с ld -melf_i386 в 32-битный исполняемый файл ELF (потому что у меня есть скрипт-обертка, который облегчает сборку + связывание + дизассемблирование, чем просто сборка).

   objdump -drwC -Mintel
8048060:       62 2c 24                bound  ebp,QWORD PTR [esp]

   objdump -drwC -Matt
8048060:       62 2c 24                bound  %ebp,(%esp)

Кажется, это причуды синтаксиса AT & T, реализованного в binutils (as / objdump / gdb), что bound требует регистр arg быть перечисленным первым.

bound  %eax, (%edx)  # assembles fine
bound (%edx), %eax   # foo.s:2: Error: operand size mismatch for `bound'

Я предполагаю, что в режиме Intel-синтаксиса он такой же, как и регистр arg, чтобы быть первым. Здесь нет никакой двусмысленности в значении, просто странный выбор дизайна, чтобы не менять местами синтаксис операндов и Intel.


Связанные: В синтаксисе AT & T также есть «ошибки» согласно руководству по GAS :

9.15.16 Ошибки синтаксиса AT & T

Ассемблер UnixWare и, возможно, другие Unix-ассемблеры ix86, производные от AT & T, генерируют инструкции с плавающей запятой с обращенными регистрами источника и назначения в некоторых случаях. К сожалению, gcc и, возможно, многие другие программы используют этот обратный синтаксис, поэтому мы застряли с ним.

Например

   fsub %st,%st(3)

приводит к обновлению %st(3) до %st - %st(3) вместо ожидаемого %st(3) - %st. Это происходит со всеми некоммутативными арифметическими операциями с плавающей запятой с двумя операндами регистра, где регистр источника равен %st, а регистр назначения - %st(i).

Таким образом, синтаксис AT & T содержит фактические ошибки, в которых оба ордера действительны и означают разные вещи. Я думаю, что мы можем сгруппировать этот операнд "обращение" с этим.


ndisasm -b32 разбирает его как 622C24 bound ebp,[esp], в соответствии с порядком операндов руководства Intel.

...