Comments 30
p.s.
mov eax, [x]
shr eax, 1
xor eax, [x]
Спасибо, не надо. У меня на работе и без того хватает кусков исходных текстов, по которым нужно догадаться, "что имел в виду автор".
Тут может быть не сразу понятно в чем дело, но это приведение 32-битного числа в младших 32 битах rax к 64-битному числу.
А чем не угодила инструкция movx? Она как раз для того и сделана, чтобы числа расширять.
То самое ощущение, что Хабр снова торт.
Спасибо!
Куча ошибок. Например, в выражении "Красиво, неправда ли" надо писать раздельно: "не правда ли".
Чем русский язык хуже FASM? Почему его не учат?
Ну вы вбейте в строку поиска на сайте hh один запрос ассемблер и другой запрос русский язык и вам все станет понятно.
Нет, это Вы сначала запятую после слова "язык" вбейте :-)
Действительно, есть такое мнение, что русский язык перестанет использоваться раньше, чем COBOL. Но я считаю это преувеличением :-))
Увы, но это не мнение - это почти факт...
Потому что Русский язык, он уже "конституционный"
Даже если и есть ошибки/опечатки в статье/посте/комментарии, много ли систем позволяют их исправить?
" хоть в в ней и присутствеут " - вот такое из этой статьи можно исправить?
когда-то много лет назад я возил с собою толстый учебник Ассемблера - самое лучшее снотворное в моей жизни - на главе об адресации засыпал гарантированно!
Вы хотите сказать, что русский язык столь же однозначен, как и ассемблер? Ну да, конечно... :/ :)
Меня больше всего этот вездесущий на Хабре "и так" добивает. "- и как? - и так!"
Автор ещё и не исправляет присланные опечатки, игнорирует.
далее rax и rcx должны содержать какие-то индексы, по котоым кладется единичка и ноль
Все же rcx и rdx. И оно на странице 0x2 :)
Еще вспомнилось, как через инструкцию AAM (деление AL на 10) можно было делить AL на любое другое значение, потому что инструкция была в два байта, а второй байт был как раз делителем. Ну и все "недокументированно" пользовались.
Прошу прощения, опечатался
И оно на странице 0x2 :)
0x2c =)
Самое интересное происходит во время выполнения инструкции
xadd
. Она складываеет два операнда, после чего меняет их местами,
Нет. Она сначала меняет их местами, а потом складывает.
После сложения с помощью инструкции
add
число изeax
из за порядка хранения байтов от младшего к старшему, попадает в младшие байты числа изrdx
Чего? С каких это пор к регистрам процессора стало применимо понятие "порядка хранения байтов"???
Нет. Она сначала меняет их местами, а потом складывает.
Просто предъявите программу, которая различает эти два варианта.
Так вот же она выше - уже предъявлена прямо в статье. (Понятно, что последователность Фибоначчи будут генерировать оба варианта поведения, но расклад результата по регистрам будет разным.)
В качестве удобного правила постарайтесь запомнить, что команды ассемблера x86 формируют результат в первом операнде (для Intel-синтаксиса). Это простое правило срабатывает и здесь: сумма после выполнения xadd
находится в первом операнде. Вот поэтому: сначала она меняет их местами, а потом складывает.
Если бы команда сначала складывала, а потом меняла местами, то сумма оказалась бы во втором операнде. Видите, какая бы ерунда получилась?
Вероятнее всего имеется ввиду little endian/big endian
Деление на "little endian/big endian" относится к тому, как старшие/младшие по значимости байты представления значения проецируются на старшие/младшие адреса памяти. Понятие "little endian/big endian" применимо только к представлению данных в адресуемой (побайтно) памяти. К регистрам процессора это деление неприменимо.
Нет, не верно.
Не имеет никакого значения, в каком порядке укладываются байты в регистре, если у нас нет возможности "увидеть" этот порядок тем или иным образом, т.е. наткнуться на некую зависимость от этого порядка. Понятия endianness не существует, пока у нас нет возможности адресовать части целого (не обязательно байты).
Кто-то может возразить, что в регистрах процессора у нас есть возможность адресовать части целого. А именно, регистр al является частью ax, ax является частью eax, а eax является частью rax. Однако эти подразделения по определению обладают не адресной семантикой, а семантикой позиционной значимости (как значимости разрядов в позиционной системе счисления). Определение eax сразу однозначно говорит нам, что это младшая по значимости часть rax. То есть это совсем не адресация, а арифметическое подразбиение, и нас тут совершенно не интересует, где и как "хранится" rax, ибо мы всегда знаем что eax обязательно даст нам младшую по арифметической значимости половину rax. То есть это не вопрос endianness вообще.
Дело в том что разница в ascii кодировке заглавных и строчных символов везде равна 20. К примеру "А" = 41, а строчная "а" = 61 или "Z" = 5a, "z" = 7a.
поправьте плиз. тут все числа даны в шестнадцатеричной системе счисления. Т.е. 0x20 и т.д, а то какая-то ерунда получается.
Тут может быть не сразу понятно в чем дело, но это приведение 32-битного числа в младших 32 битах rax к 64-битному числу.
Правильнее было бы сказать "знаковое расширение 32-битного числа до 64 битов". Потому что если в eax было отрицательное число, то после сложения с 0xffffffff80000000 старшие биты rax станут нулями из-за переноса из 31-го разряда, а после xor -- опять станут единицами, как и положено отрицательному числу.
Трюк имеет смысл, потому что позволяет (изменением битовой маски загружаемой в rdx) выполнять знаковое расширение исходного числа с произвольным количеством битов, в отличие от инструкций movsx, работающих только с байтами/словами.
Ассeмблерные хаки из книги «xchg rax, rax»