GCC Accemбляр , pavlinux, 22-Дек-09, 03:35 [смотреть все]#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,... или я чёй-то не вкурю...
|
- GCC Accemбляр , pavlinux, 04:00 , 22-Дек-09 (1)
>#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 Так?
- GCC Accemбляр , const86, 10:44 , 22-Дек-09 (2)
> 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; }
- GCC Accemбляр , pavlinux, 14:49 , 22-Дек-09 (3)
>Мне не нравится, что в списке переменных 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));
- GCC Accemбляр , const86, 15:27 , 22-Дек-09 (4)
>! __asm__ __volatile__ ("xchg %Йx, %%eсx" : "=a"(x), "=с"(y) : "a"(x), "с"(y)); >... >main+31: xchg Йx,Мx Чудеса...
- GCC Accemбляр , const86, 15:27 , 22-Дек-09 (5)
>>! __asm__ __volatile__ ("xchg %eax, %%eсx" : "=a"(x), "=с"(y) : "a"(x), "с"(y)); >>... >>main+31: xchg %eax,%edx > >Чудеса...
|