Я нашел в Интернете эту удивительную книгу xchg rax, rax от xorpd. Это сборник загадок сборки. Книга содержит короткие ассемблерные фрагменты 0x40 без текста.
Я только начал это читать, и это потрясающе. Я обновлю это сообщение в блоге, добавив объяснения фрагментов, которые я исследую.
xchg rax, rax - объяснение 0x00
Подсказка: это 0-й фрагмент.
Этот фрагмент просто иллюстрирует несколько различных способов установки регистров в 0. Он устанавливает eax, ebx, ecx, edx, esi, edi и ebp в 0 в том же порядке.
xchg rax, rax - 0x01 объяснение
Фибоначчи
xchg rax, rax - 0x02 объяснение
Устанавливает rax в 0, если начальное значение равно 0. В противном случае он всегда устанавливает его в 1.
xchg rax, rax - 0x03 объяснение
На самом деле этот код - умный способ сделать rax = min(rax, rdx)
без ответвлений.
sub rdx, rax ; rdx = rdx - rax; CF set if rdx < rax
sbb rcx, rcx ; rcx = all 1 bits if CF was set, 0 otherwise
and rcx, rdx ; rcx = rdx - rax if CF was set, 0 otherwise
add rax, rcx ; rax = rax + (rdx - rax) = rdx if CF was set, unchanged otherwise
Более читаемая версия ветвления:
cmp rdx, rax
jnc done ; if rdx - rax produced no carry, rax is smaller or equal
mov rax, rdx ; otherwise rdx is the smaller one
done:
Он все еще использует CF для проверки переполнения.
Из ответа Шута здесь.
xchg rax, rax - 0x04 объяснение
0x20 в двоичном формате - это 00100000
Таким образом, xорирование числа с помощью 0x20 изменит 5-й наиболее значимый бит. Теперь, если мы увидим представление символа ascii в двоичном формате, есть кое-что интересное, на что стоит обратить внимание.
A = 0100 0001 a = 0110 0001 B = 0100 0010 b = 0110 0010
Вот мы и видим. Переворачивание пятого бита переворачивает регистр (нижний / верхний) буквы.