Pull to refresh

Comments 30

Прикольно, но уж больно много допущений делает автор. Надо догадываться буквально обо всём, о параметрах, об очень ограниченной применимости и т.д. Но как головоломка — годится :)
p.s.
mov eax, [x]
shr eax, 1
xor eax, [x]
y = x ^ (x / 2);

Кому любопытно,

Это

Код Грея

Спасибо, не надо. У меня на работе и без того хватает кусков исходных текстов, по которым нужно догадаться, "что имел в виду автор".

Тут может быть не сразу понятно в чем дело, но это приведение 32-битного числа в младших 32 битах rax к 64-битному числу.

А чем не угодила инструкция movx? Она как раз для того и сделана, чтобы числа расширять.

Честно говоря не знаю, может автору она по какой-то причине не нравится, но думаю что мы этого уже не узнаём

То самое ощущение, что Хабр снова торт.

Спасибо!

Куча ошибок. Например, в выражении "Красиво, неправда ли" надо писать раздельно: "не правда ли".

Чем русский язык хуже FASM? Почему его не учат?

Ну вы вбейте в строку поиска на сайте hh один запрос ассемблер и другой запрос русский язык и вам все станет понятно.

Нет, это Вы сначала запятую после слова "язык" вбейте :-)

Действительно, есть такое мнение, что русский язык перестанет использоваться раньше, чем COBOL. Но я считаю это преувеличением :-))

Увы, но это не мнение - это почти факт...
Потому что Русский язык, он уже "конституционный"
Даже если и есть ошибки/опечатки в статье/посте/комментарии, много ли систем позволяют их исправить?
" хоть в в ней и присутствеут " - вот такое из этой статьи можно исправить?

когда-то много лет назад я возил с собою толстый учебник Ассемблера - самое лучшее снотворное в моей жизни - на главе об адресации засыпал гарантированно!

Вы хотите сказать, что русский язык столь же однозначен, как и ассемблер? Ну да, конечно... :/ :)

Да ну нет, вряд-ли но может быть

Меня больше всего этот вездесущий на Хабре "и так" добивает. "- и как? - и так!"

Автор ещё и не исправляет присланные опечатки, игнорирует.

далее rax и rcx должны содержать какие-то индексы, по котоым кладется единичка и ноль

Все же rcx и rdx. И оно на странице 0x2 :)

Еще вспомнилось, как через инструкцию AAM (деление AL на 10) можно было делить AL на любое другое значение, потому что инструкция была в два байта, а второй байт был как раз делителем. Ну и все "недокументированно" пользовались.

Прошу прощения, опечатался

Самое интересное происходит во время выполнения инструкции xadd. Она складываеет два операнда, после чего меняет их местами,

Нет. Она сначала меняет их местами, а потом складывает.

После сложения с помощью инструкции add число изeax из за порядка хранения байтов от младшего к старшему, попадает в младшие байты числа из rdx

Чего? С каких это пор к регистрам процессора стало применимо понятие "порядка хранения байтов"???

Нет. Она сначала меняет их местами, а потом складывает.

Просто предъявите программу, которая различает эти два варианта.

Так вот же она выше - уже предъявлена прямо в статье. (Понятно, что последователность Фибоначчи будут генерировать оба варианта поведения, но расклад результата по регистрам будет разным.)

В качестве удобного правила постарайтесь запомнить, что команды ассемблера x86 формируют результат в первом операнде (для Intel-синтаксиса). Это простое правило срабатывает и здесь: сумма после выполнения xadd находится в первом операнде. Вот поэтому: сначала она меняет их местами, а потом складывает.

Если бы команда сначала складывала, а потом меняла местами, то сумма оказалась бы во втором операнде. Видите, какая бы ерунда получилась?

Вероятнее всего имеется ввиду little endian/big endian

Деление на "little endian/big endian" относится к тому, как старшие/младшие по значимости байты представления значения проецируются на старшие/младшие адреса памяти. Понятие "little endian/big endian" применимо только к представлению данных в адресуемой (побайтно) памяти. К регистрам процессора это деление неприменимо.

Вы жестоко заблуждаетесь. Таки порядок байт в регистре имеет свойство быть. Различают big-endian и little-endian системы как раз из-за маппинга байт в регистре процессора. Опять же little- и big-endian запись не требует наличия именно побайтовой адресации. Возьмем память, адресуемую по 4 байта — 0xaabbccdd и 0xddccbbaa — endiannes является просто абстракцией для порядка записи. Даже если в регистрах процессора нет адресов, байты все равно укладываются в каком-либо порядке, то есть адресация присутствует

Нет, не верно.

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

Кто-то может возразить, что в регистрах процессора у нас есть возможность адресовать части целого. А именно, регистр al является частью ax, ax является частью eax, а eax является частью rax. Однако эти подразделения по определению обладают не адресной семантикой, а семантикой позиционной значимости (как значимости разрядов в позиционной системе счисления). Определение eax сразу однозначно говорит нам, что это младшая по значимости часть rax. То есть это совсем не адресация, а арифметическое подразбиение, и нас тут совершенно не интересует, где и как "хранится" rax, ибо мы всегда знаем что eax обязательно даст нам младшую по арифметической значимости половину rax. То есть это не вопрос endianness вообще.

Функции print_number самое место в хабе «Ненормальное программирование».

Дело в том что разница в ascii кодировке заглавных и строчных символов везде равна 20. К примеру "А" = 41, а строчная "а" = 61 или "Z" = 5a, "z" = 7a.

поправьте плиз. тут все числа даны в шестнадцатеричной системе счисления. Т.е. 0x20 и т.д, а то какая-то ерунда получается.

Тут может быть не сразу понятно в чем дело, но это приведение 32-битного числа в младших 32 битах rax к 64-битному числу.

Правильнее было бы сказать "знаковое расширение 32-битного числа до 64 битов". Потому что если в eax было отрицательное число, то после сложения с 0xffffffff80000000 старшие биты rax станут нулями из-за переноса из 31-го разряда, а после xor -- опять станут единицами, как и положено отрицательному числу.

Трюк имеет смысл, потому что позволяет (изменением битовой маски загружаемой в rdx) выполнять знаковое расширение исходного числа с произвольным количеством битов, в отличие от инструкций movsx, работающих только с байтами/словами.

Sign up to leave a comment.

Articles

Change theme settings