Я нашел в Интернете эту удивительную книгу 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

Вот мы и видим. Переворачивание пятого бита переворачивает регистр (нижний / верхний) буквы.