The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]




Версия для распечатки Пред. тема | След. тема
Новые ответы [ Отслеживать ]
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));




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру