Как относительный JMP (x86) реализован в Ассемблере?

При создании моего ассемблера для x86 платформы я встретился с некоторыми проблемами с кодированием JMP инструкция:

OPCODE   INSTRUCTION   SIZE
 EB cb     JMP rel8     2
 E9 cw     JMP rel16    4 (because of 0x66 16-bit prefix)
 E9 cd     JMP rel32    5
 ...

(с моего любимого x86 веб-сайта инструкции, http://siyobik.info/index.php?module=x86&id=147)

Все - относительные переходы, где размер каждого кодирования (операция + операнд) находится в третьем столбце.

Теперь мой оригинал (и таким образом дают сбой из-за этого) дизайн зарезервировал максимальное (5-байтовое) пространство для каждой инструкции. Операнд еще не известен, потому что это - переход к все же неизвестному местоположению. Таким образом, я реализовал "переписать" механизм, который переписывает операнды в корректном месте в памяти, если местоположение перехода известно и заполняет остальных NOPs. Это - несколько серьезное беспокойство в жестких циклах.

Теперь моя проблема со следующей ситуацией:

b: XXX
c: JMP a
e: XXX
   ...
   XXX
d: JMP b
a: XXX      (where XXX is any instruction, depending
             on the to-be assembled program)

Проблема состоит в том, что я хочу самое маленькое кодирование для a JMP инструкция (и нет NOP заполнение).

Я должен знать размер инструкции в c прежде чем я смогу вычислить относительное расстояние между a и b для операнда в d. То же касается JMP в c: это должно знать размер d прежде чем это сможет вычислить относительное расстояние между e и a.

Как существующие ассемблеры решают эту проблему, или как Вы сделали бы это?

Это - то, что я думаю, который решает проблему:

Сначала закодируйте все инструкции к кодам операций между JMP и это - цель, если этот регион содержит код операции переменного размера, используйте максимальный размер, например. 5 для a JMP. Затем закодируйте родственника JMP к он - цель путем выбора самого маленького размера кодирования (3, 4 или 5), и вычислите расстояние. Если какой-либо код операции переменного размера кодируется, измените все абсолютные операнды прежде и все относительные инструкции, который перескакивает через эту закодированную инструкцию: они повторно кодируются, когда их операнд изменяется для выбора самого маленького размера. Этот метод, как гарантируют, закончится, поскольку коды операций переменного размера только могут уменьшиться (потому что он использует максимальный размер их).

Интересно, возможно, это - сверхспроектированное решение, вот почему я задаю этот вопрос.

8
задан Pindatjuh 11 May 2010 в 22:09
поделиться

2 ответа

Вот один из использованных мной подходов, который может показаться неэффективным, но оказывается не подходящим для большинства реального кода (псевдокода):

IP := 0;
do
{
  done = true;
  while (IP < length)
  {
    if Instr[IP] is jump
      if backwards
      { Target known
          Encode short/long as needed }
      else
      {  Target unknown
          if (!marked as needing long encoding) // see below
            Encode short
          Record location for fixup }
    IP++;
  }
  foreach Fixup do
    if Jump > short
      Mark Jump location as requiring long encoding
      PC := FixupLocation; // restart at instruction that needs size change
      done = false; 
      break; // out of foreach fixup
    else
      encode jump
} while (!done);
1
ответ дан 6 December 2019 в 00:05
поделиться

На первом проходе у вас будет очень хорошее приближение к тому, какой код jmp использовать, используя пессимистический подсчет байтов для всех инструкций перехода.

На втором проходе вы можете заполнить переходы выбранным пессимистическим кодом операции. Затем можно было переписать очень небольшое количество переходов, чтобы использовать на один или два байта меньше, только те, которые были очень близки к пороговому значению перехода 8/16 бит или 16/32 байта изначально. Поскольку все кандидаты представляют собой переходы из многих байтов, они с меньшей вероятностью окажутся в критических ситуациях цикла, поэтому вы, вероятно, обнаружите, что дальнейшие проходы мало или совсем не дают преимущества по сравнению с двухпроходным решением.

3
ответ дан 6 December 2019 в 00:05
поделиться
Другие вопросы по тегам:

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