=
в =X
означает, что это ограничение ТОЛЬКО ДЛЯ ВЫХОДА (в отличие от ограничения на обновление с +
). Это означает, что ассемблерный код должен что-то записывать в операнд (в %0
), и это будет иметь значение, которое выводится. Но так как ваш ассемблерный код никогда не записывает в %0
, вы получаете все, что происходит с мусором в этом месте (вероятно, регистр, который выбрал распределитель регистров).
Попробуйте добавить строку mov %%rcx,%0
в код asm, чтобы увидеть, что на самом деле происходит.
Скорее всего, что вы действительно хотите, это что-то вроде:
__asm__ volatile (
"mov %[size], %%rbx \n"
"loop: \n"
"movb $1, (%[out]) \n"
"add $1, %[out] \n"
"sub $1, %%rbx \n"
"jnz loop \n"
: [out]"+r"(buffer) //outputs
: [size]"X"(size) //inputs
: "rbx", "memory" //clobbers
);
Обратите внимание, что это оставляет buffer
указывающим после вставленных значений (в конце буфера) - не ясно, если это то, что вы хотите. Вы можете сделать то же самое с размером, делая его еще проще:
__asm__ volatile (
"loop: \n"
"movb $1, (%[out]) \n"
"add $1, %[out] \n"
"sub $1, %[size] \n"
"jnz loop \n"
: [out]"+r"(buffer), [size]"+X"(size) //outputs
: //inputs
: "memory" //clobbers
);
Хотя было бы еще проще (и лучше для оптимизатора) вообще не использовать asm:
do { *buffer++ = '\1'; } while (--size);
Итак, чтобы подвести итог всем комментариям ниже, вам может понадобиться что-то вроде:
long size = 100;
char buffer[100];
char *temp;
__asm__(
"loop: \n"
"movb $1, (%[out]) \n"
"add $1, %[out] \n"
"sub $1, %[size] \n"
"jnz loop \n"
: [out]"=r"(temp), [size]"+X"(size), "=m"(buffer) //outputs
: "0"(buffer) // inputs
) // no clobbers
- использование ограничения
"=m"
на весь буфер вместо сабблеров памяти и энергозависимости означает, что он может быть исключен из мертвого кода, если не используется ни один из результатов
- использование временного указателя для перемещения указателя над буфером означает, что исходное значение буфера (начальное) может быть сохранено.
- если вы должны использовать malloc для буфера,
"=m"(*(char (*)[100])buffer)
может использоваться для получения ограничения на весь буфер.
Однако, я поддерживаю свой предыдущий комментарий, что писать его без asm лучше; это проще и легче понять, и оптимизатор компилятора, вероятно, векторизует его для вас.