diff --git a/02-cpu-commnads/README.md b/02-cpu-commnads/README.md index f8a0042..1259ced 100644 --- a/02-cpu-commnads/README.md +++ b/02-cpu-commnads/README.md @@ -16,9 +16,17 @@ Хтонь лично на мой взгляд довольно неприятная, но на самом деле она не так страшна, как вы подумали... Она значительно хуже... -Пояснительную бригаду относительно суффиксов, префиксов, буковок и циферок, которые в табличке есть мы можем найти в начале (~44 страница). С вашего позволения я просто повторю то, что там написано с незанчительными комментариями +В общем я тут свои пояснения ко всему, что указывают сами Intel, но по простяге и на основе опыта ручного ассемблирования (который к слову не очень богат, потому что я еще не успел настолько сойти с ума, чтобы делать работу ассемблера за него) -- `REX.W` - Показывает, что REX префикс затрагивает размер операндов или меняет значение инструкции. Подробнее об этом они писали во второй главе. Учтите, что префиксы REX, которые повышают инструкции до работы с 64 битами не приводятся явно в колонке opcode. +- `REX.W` - По идее этот префикс может означать много вещей, но на практике пока что я сталкивался с ним только в таком разрезе: если он есть в начале, значит в REX-байте нужно поставить единичку в 3 разряде (4-я цифра справа). Также это означает, что данный байт вообще говоря обязателен для функционирования этой команды + +- `REX` - Такое встречается на моей памяти только рядом с восьмибитными инструкциями и всегда только для того, чтобы к ним тут же приложилось пояснение от intel, что какие-то там проблемы. В общем читайте все это в сносках, потому что сам по себе флаг обозначает простое наличие REX-байта перед опкодом по всей видимости +- `/digit` - можно порой встретить что-то типа `/0` или `/7`. Когда такое видите, это значит, что в ModR/M байте вместо поля reg нужно записать 2 запись числа, которое после слеша. То есть от `000` и до `111`. А все остальное адресуете как раньше +- `/r` - указывает на то, что в ModR/M байте все поля Mod, Reg и R/M используются в стандартном варианте +- `cb`, `cw`, `cd`, `cp`, `co`, `ct` - сам плохо понимаю, что это за покемоны такие. В 64-битных опкодах встречаются редко. Согласно мануалу показывают, сколько битов после опкода следует зарезервировать под смещение для сегмента кода (если вы откроете методичку мелицины, то это тот самый CS или Code Segment). Также согласно мануалу иногда оно может переназначить новое значение сегментному регистру кода. Возможны варианты 1 байт, 2 байта, 4 байта, 6 байт, 8 байт, 10 байт соотвественно. +- `ib`, `iw`, `id`, `io` - Показывают, что после опкода, ModR/M байта (если есть) должен идти непосредственный операнд длиной 1, 2, 4, 8 байт соответственно. Встречается он в таблице обычно там же, где в колонке instruction в соответствующем месте производятся какие-то действия с непосредственными операндами. При чем надо понимать, что нельзя просто опустить байты, которые заполнены нулями, даже если очень хочется и мама разрешила. ставим столько, сколько требует спецификация +- `+rb`, `+rw`, `+rd`, `+ro` - встречается тогда, когда создатели процессора почему-то решили засунуть регистр прям в опкод операнда. Ну, не нам их за это судить. Фактически нам нужно просто глянуть в таблицу которая приведена самими интелами, чтобы определиться только с тем, какое число от 0 до 7 прибавлять. В целом это число является номером регистра, а идут они всегда в следующем порядке: rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi, а также дополнительные регистры r8-r15 работают в том же режиме, то есть начинают нумероваться с нуля. Единственное отличие - бит в REX байте нужно поставить. А вообще табличка должен сказать весьма любопытная, поэтому с ней придется ознакомиться самому. Находится она на 45 странице руководства. +- `+i` - используется в операциях с плавающей точкой. Такие операции любят использовать стек сопроцессора (потому что на самом деле вся арифметика с плавающей точкой аппаратно ускоряется и у нее тоже есть собственная память). Так вот, такое стек обозначается ST(i). Где ST(0) - вершина стека. Не берусь утверждать, но по всей видимости в стеке всего 8 ячеек, потому что по мануалу i может принимать значения от 0 до 7. Соотвественно наша задача просто прибавить это число к байту слева от плюса и на этом все. Больше ничего не требуется ### Чутка про префикс REX