#define swap(a, b) __asm__ __volatile__ (\
"xchg %0, %1" \
: "=r"(a), "=r"(b) \
: "r"(b), "r"(a)); /* Правильно ли? */int main(void)
{
char a = 'X';
char b = 'Z';swap(a,b);
printf("%s, %s\n", a, b);return(0);
}Собственно, работает, но мучают меня сомнения,
по поводу строки - : "r"(b), "r"(a));Получается, что я сам поменял местами (a) и (b),
а не операция xchg,... или я чёй-то не вкурю...
>#define swap(a, b) __asm__ __volatile__ (\
>
> "xchg %0, %1"
> \
> : "=r"(a), "=r"(b) \
>
> : "r"(b), "r"(a));Дизассм сказал:
Как я понимаю
movl -4(%rbp), %eax # это a = 'X';
movl -8(%rbp), %edx # это b = 'Z';xchg %edx, %eax # собственно команда
movl %edx, -8(%rbp) # пихнуть edx в b
movl %eax, -4(%rbp) # и eax в aТак?
> xchg %edx, %eax # собственно команда
>
> movl %edx, -8(%rbp) # пихнуть edx в b
> movl %eax, -4(%rbp) # и eax в aКрасота! А если убрать асм и сделать старым дедушкиным методом с временной переменной, то компилятор сделает те же два movl, только поменяет edx и eax - и xchg вапще нинужен!
Мне не нравится, что в списке переменных asm четыре переменных, а в коде ссылка только на две. Не знаю, как это исправить, пользуясь автоматическим выбором регистра. Я бы написал явно, примерно так:
void hyperswap(int *p, int *q) {
int x = *p, y = *q;
asm ("xchg %%eax, %%ecx\n" : "=a" (x), "=c" (y) : "a" (x), "c" (y));
*p = x, *q = y;
}
>Мне не нравится, что в списке переменных asm четыре переменных, а вПочаму 4, две x, y: x = -4(%rbp), y = -8(%rbp)
>коде ссылка только на две. Не знаю, как это исправить, пользуясь
>автоматическим выбором регистра. Я бы написал явно, примерно так:
>
>void hyperswap(int *p, int *q) {
> int x = *p, y = *q;
> asm ("xchg %%eax, %%ecx\n" : "=a" (x), "=c" (y) : "a"
>(x), "c" (y));
> *p = x, *q = y;
>}У меня всё равно пихается в EDX, и появляется лишний mov
!
! __asm__ __volatile__ ("xchg %%eax, %%eсx" : "=a"(x), "=с"(y) : "a"(x), "с"(y));
main+22: mov -0x8(%rbp),%eax
main+25: mov -0x4(%rbp),%eсx
main+28: mov %eсx, %edx :)
main+31: xchg %eax,%edx
main+32: mov %eax,-0x8(%rbp)
main+33: mov %edx,-0x4(%rbp)
!Вот так работат.
__asm__ __volatile__ ("xchg %%eax, %%edx" : "=a"(x), "=d"(y) : "a"(x), "d"(y));
>! __asm__ __volatile__ ("xchg %Йx, %%eсx" : "=a"(x), "=с"(y) : "a"(x), "с"(y));
>...
>main+31: xchg Йx,МxЧудеса...
>>! __asm__ __volatile__ ("xchg %eax, %%eсx" : "=a"(x), "=с"(y) : "a"(x), "с"(y));
>>...
>>main+31: xchg %eax,%edx
>
>Чудеса...