rbp не разрешен в качестве базы SIB? - PullRequest
0 голосов
/ 26 сентября 2018

Я совершенно новичок в двоичном кодировании x86-64.Я пытаюсь исправить какой-то старый код на «ассемблере».

В любом случае, я пытаюсь сделать что-то вроде этого (синтаксис Intel):

mov    [rbp+rcx], al

В настоящее время ассемблер генерирует это:

88 04 0D

но это не является действительной инструкцией.Если я изменю базу в SIB-байте с rbp на какой-либо другой регистр, он будет работать нормально.Другой способ заставить это работать - добавить однобайтовое смещение нуля (88 44 0D 00).Похоже, это происходит с другими подобными кодами операций.

Почему я не могу использовать rbp там с mod=00?

1 Ответ

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

Кодировка, которая будет означать rbp, является управляющим кодом без базового регистра (просто disp32 в SIB или RIP-относительный rel32 в ModRM).Большинство ассемблеров собирают [rbp] в [rbp + disp8=0].


Так как вам не нужно масштабировать его, используйте вместо этого [rcx + rbp], чтобы избежать необходимости в disp8 = 0, потому что rbp может быть индексом.

(SS и DS всегда эквивалентны в длинном режиме, поэтому не имеет значения, что base = RBP подразумевает SS, а base = RCX подразумевает использование DSсегмент.)


x86 / x86-64 Режим адресации ModRM, кодирующий особые случаи

(из ответа, который я написал на Почему rbp и rsp называются регистрами общего назначения? ).Этот вопрос выглядит как идеальное место для копирования или трансплантации этого раздела.

rbp / r13 не может быть базовым регистром без смещения : эта кодировка вместо этого означает: (в ModRM) rel32 (относительно RIP) или (в SIB) disp32 без базового регистра.(r13 использует те же 3 бита в ModRM / SIB, поэтому этот выбор упрощает декодирование, не заставляя декодер длины команды смотреть на бит REX.B для получения 4-го бита базового регистра).[r13] собирается до [r13 + disp8=0].[r13+rdx] собирается в [rdx+r13] (чтобы избежать проблемы путем замены базы / индекса, когда это опция).

rsp / r12, поскольку базовому регистру всегда требуется байт SIB .(Кодирование ModR / M base = RSP является escape-кодом для сигнализации байта SIB, и снова, больше декодера должно заботиться о префиксе REX, если r12 обрабатывается по-другому).

rsp не может быть индексным регистром .Это позволяет кодировать [rsp], что более полезно, чем [rsp + rsp].(Корпорация Intel могла бы разработать кодировки ModRM / SIB для 32-битных режимов адресации (впервые в 386), поэтому SIB без индекса возможен только при base = ESP. Это позволило бы [eax + esp*4] и исключить [esp + esp*1/2/4/8]Но это бесполезно, поэтому они упростили аппаратное обеспечение, сделав index = ESP кодом без индекса независимо от базы. Это позволяет использовать два избыточных способа кодирования любого режима адресации base или base + disp: с или без SIB.)

r12 может быть индексным регистром .В отличие от других случаев, это не влияет на декодирование длины команды.Кроме того, его нельзя обойти с помощью более длинной кодировки, как в других случаях.AMD хотела, чтобы регистр AMD64 был как можно более ортогональным, поэтому имеет смысл потратить несколько дополнительных транзисторов на проверку REX.X как часть декодирования индекса / без индекса.Например, [rsp + r12*4] требует index = r12, так что если r12 не является полностью предназначенным, то это сделает AMD64 худшей целью компилятора.

   0:   41 8b 03                mov    eax,DWORD PTR [r11]
   3:   41 8b 04 24             mov    eax,DWORD PTR [r12]      # needs a SIB like RSP
   7:   41 8b 45 00             mov    eax,DWORD PTR [r13+0x0]  # needs a disp8 like RBP
   b:   41 8b 06                mov    eax,DWORD PTR [r14]
   e:   41 8b 07                mov    eax,DWORD PTR [r15]
  11:   43 8b 04 e3             mov    eax,DWORD PTR [r11+r12*8] # *can* be an index

Все это также относится к 32-битным режимам адресации;кодировка идентична, за исключением того, что нет EIP-относительного кодирования, только два избыточных способа кодирования disp32 без основы.

См. также https://wiki.osdev.org/X86-64_Instruction_Encoding#32.2F64-bit_addressing_2 для таблиц, подобных таблицам в Intel vol.2manual.


Похоже, что это происходит с другими подобными кодами операций.

Кодирование ModRM операндов r / m всегда одинаково.Некоторые коды операций требуют операнда регистра, а некоторые требуют памяти, но фактическое ModRM + необязательное смещение SIB + исправлено, поэтому одно и то же оборудование может декодировать его независимо от инструкции.

Существует несколько редких кодов операций, таких как mov al/ax/eax/rax, [qword absolute_address], которые вообще не используют кодирование ModRM для своих операндов, но все, которые используют тот же формат.

...