Как перевести синтаксис Intel в синтаксис AT&T? (ассемблерная вставка в СИ) - Assembler
Формулировка задачи:
Извиняюсь, что, возможно, пишу не в ту тему.
Нужен именно AT&T синтаксит. В качестве примера для курсовой я разбираю перемножение соответствующих элементов массивов с помощью SSE инструкций. Синтаксис Intel является не родным для компилятора GCC, поэтому с ним постоянно возникают проблемы, причём в разных версиях компилятора разные: то регистры eax недопустимы, то ex, то перевод синтаксиса в at&t недопустим, и куча других, а если скомпилируется, то возникает ошибка segmentation fault.
Вставка, написанная с использованиемсинтаксиса AT&T работает без проблем, но перевод, сделанный по мануалу на википедии не компилируется.
Как перевести код на AT&T синтаксис? Вот код вставки:
arr1, arr2 и arr3 имеют тип float*, count — long.
P.S. Вставки сделанные с помощью конструкции __asm { ... }; тоже не компилируются. Версия GCC: 4.4.7.
__asm__ volatile ( ".intel_syntax noprefix \n\t" "loop: \n\t" "movups xmm0, [eax+edx] \n\t" "movups xmm1, [ebx+edx] \n\t" "mulps xmm0, xmm1 \n\t" "movups [ecx+edx], xmm0 \n\t" "sub edx, 16 \n\t" "jnz loop \n\t" ".att_syntax prefix \n\t" : : "a"(arr1), "b"(arr2), "c"(arr3), "d"(count) : "xmm0", "xmm1" );
Решение задачи: «Как перевести синтаксис Intel в синтаксис AT&T? (ассемблерная вставка в СИ)»
textual
Листинг программы
#include <stdio.h> #include <stdlib.h> int main() { long amount = 100000; // Должно быть кратно 4 float *vectorA, *vectorB, *vectorC; vectorA = (float*)malloc(amount * sizeof(float)); vectorB = (float*)malloc(amount * sizeof(float)); vectorC = (float*)malloc(amount * sizeof(float)); for(long i = 0; i < amount; ++i) { vectorA[i] = (float)rand() / 100000; vectorB[i] = (float)rand() / 100000; vectorC[i] = 0.0; } __asm__ volatile ( "loop: \n\t" "subq $0x10, %%rdx \n\t" // Понижение адресной метки на 4 float'а "movups (%%rax,%%rdx), %%xmm0 \n\t" // Загружает 4 числа в первый регистр (xmm0) "movups (%%rbx,%%rdx), %%xmm1 \n\t" // Загружает 4 числа во второй регистр (xmm1) "mulps %%xmm1, %%xmm0 \n\t" // Перемножает оба векторных регистра "movups %%xmm0, (%%rcx,%%rdx) \n\t" // Записывает результат в память "jnz loop \n\t" : : "a"(vectorA), "b"(vectorB), "c"(vectorC), "d"(amount) : "xmm0", "xmm1" ); free(vectorA); free(vectorB); free(vectorC); return 0; }
Объяснение кода листинга программы
- Синтаксис программы: Программа написана на языке C и содержит ассемблерную вставку.
- Выделение памяти: В начале программы выделяется память под три указателя на float.
- Инициализация векторов: Затем, с помощью генератора случайных чисел, инициализируются два вектора (vectorA и vectorB) с 4 случайными числами в каждом. Третий вектор (vectorC) инициализируется нулями.
- Ассемблерная вставка: Далее следует ассемблерная вставка, которая выполняет перемножение двух векторов и сохранение результата в третий вектор.
- Освобождение памяти: В конце программы освобождается выделенная память.
- Условие цикла: В ассемблерной вставке используется цикл, который продолжается до тех пор, пока дескриптор (rdx) не станет кратным 4.
- Загрузка и перемножение векторов: Внутри цикла загружаются два вектора в соответствующие регистры (xmm0 и xmm1) и выполняется операция перемножения.
- Сохранение результата: Результат перемножения записывается обратно в память по адресу, указанному в регистре rcx с учетом смещения, определяемого дескриптором.
- Свободно используемые регистры: В ассемблерной вставке используются регистры rdx, rax и rbx, а также регистры xmm0 и xmm1.
- Свободно используемые библиотеки: В программе используются стандартные библиотеки C stdlib.h и printf.h.
- Синтаксис ассемблера: Ассемблерная вставка использует синтаксис Intel.
- Вывод: Программа не содержит операций вывода, поэтому она не выводит никаких чисел.
- Использование операции jnz: В ассемблерной вставке используется операция jnz (или jmp), которая продолжает цикл, если условие истинно.
- Использование операции mulps: В ассемблерной вставке используется операция mulps, которая выполняет перемножение двух векторов.
- Использование операции movups: В ассемблерной вставке используется операция movups, которая загружает или сохраняет 4 числа из или в память.
- Использование оператора ',': В ассемблерной вставке используется оператор запятой (,), который используется для перегрузки операндов.
- Использование регистров rdx, rax и rbx: В ассемблерной вставке используются регистры rdx, rax и rbx для адресации памяти и выполнения операций.
- Использование регистров xmm0 и xmm1: В ассемблерной вставке используются регистры xmm0 и xmm1 для хранения векторов.
- Использование директивы 'volatile': Ассемблерная вставка объявлена как volatile, что означает, что она будет выполняться точно так, как написана, и не будет оптимизирована компилятором.
- Указатели на функции: В программе используются функции malloc и free для выделения и освобождения памяти, а также функция rand для генерации случайных чисел.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д