Обмен переменных через XOR - тонкости - C (СИ)
Формулировка задачи:
main()
{
int a=5, b=10;
a^=b; b^=a; a^=b; printf("%d %d", a, b);
}main()
{
int a=5, b=10;
a^=b^=a^=b; printf("%d %d", a, b);
}учебных
программах. Однако, как сегодня выяснилось, вторая запись перестает работать, если вынести обмен в функцию:void swap(int *a, int *b)
{
*a^=*b; *b^=*a; *a^=*b;
}
main()
{
int a=5, b=10;
swap(&a, &b); printf("%d %d", a, b);
}void swap(int *a, int *b)
{
*a^=*b^=*a^=*b;
}
main()
{
int a=5, b=10;
swap(&a, &b); printf("%d %d", a, b);
}Решение задачи: «Обмен переменных через XOR - тонкости»
textual
Листинг программы
main_1.c **** void swap(int *a, int *b)
4:main_1.c **** {
10 .loc 1 4 0
11 .cfi_startproc
12 0000 55 push rbp
13 .cfi_def_cfa_offset 16
14 .cfi_offset 6, -16
15 0001 4889E5 mov rbp, rsp
16 .cfi_def_cfa_register 6
17 0004 48897DF8 mov QWORD PTR [rbp-8], rdi
18 0008 488975F0 mov QWORD PTR [rbp-16], rsi
5:main_1.c **** *a^=*b;
19 .loc 1 5 0
20 000c 488B45F8 mov rax, QWORD PTR [rbp-8]
21 0010 8B10 mov edx, DWORD PTR [rax]
22 0012 488B45F0 mov rax, QWORD PTR [rbp-16]
23 0016 8B00 mov eax, DWORD PTR [rax]
24 0018 31C2 xor edx, eax
25 001a 488B45F8 mov rax, QWORD PTR [rbp-8]
26 001e 8910 mov DWORD PTR [rax], edx
6:main_1.c **** *b^=*a;
27 .loc 1 6 0
28 0020 488B45F0 mov rax, QWORD PTR [rbp-16]
29 0024 8B10 mov edx, DWORD PTR [rax]
30 0026 488B45F8 mov rax, QWORD PTR [rbp-8]
31 002a 8B00 mov eax, DWORD PTR [rax]
32 002c 31C2 xor edx, eax
33 002e 488B45F0 mov rax, QWORD PTR [rbp-16]
34 0032 8910 mov DWORD PTR [rax], edx
7:main_1.c **** *a^=*b;
35 .loc 1 7 0
36 0034 488B45F8 mov rax, QWORD PTR [rbp-8]
37 0038 8B10 mov edx, DWORD PTR [rax]
38 003a 488B45F0 mov rax, QWORD PTR [rbp-16]
39 003e 8B00 mov eax, DWORD PTR [rax]
40 0040 31C2 xor edx, eax
41 0042 488B45F8 mov rax, QWORD PTR [rbp-8]
42 0046 8910 mov DWORD PTR [rax], edx
8:main_1.c ****
9:main_1.c **** }
Объяснение кода листинга программы
Код представлен без комментариев, так как они могут быть неактуальными или даже неверными, а также могут затруднять чтение кода. Список переменных и их значений:
- a, b - указатели на переменные, которые будут меняться местами
- rbp, rsp - регистры, используемые для управления стеком вызовов
- edx, eax - временные регистры, используемые в операциях XOR Описание кода:
- Сначала функция swap() объявляется как пустая функция с двумя указателями на int в качестве параметров и без возвращаемого значения.
- Затем создается стек вызовов с помощью push rbp и mov rbp, rsp.
- Далее, QWORD PTR [rbp-8] и QWORD PTR [rbp-16] используются для загрузки значений a и b в регистры edx и eax соответственно.
- Затем выполняется операция XOR с использованием xor edx, eax.
- После этого значения a и b сохраняются обратно в память с помощью mov DWORD PTR [rax], edx.
- Наконец, функция завершается с помощью pop rbp и ret. Поскольку код является функцией, он не имеет собственного состояния или переменных, которые необходимо инициализировать или очистить.