Написать программу решения на с++ с ассемблеровски...
Создано: 13 апреля 2025 г.
Создано: 13 апреля 2025 г.
Написать программу решения на с++ с ассемблеровскими вкраплениями на visual studio.На с++ только ввод вывод и объявление переменных
В одномерном динамическом массиве целых чисел длиной в слово четной размерности поменять местами первую половину массива со второй.
Массив заполнить генератором случайных чисел на C++.
Ниже — полный пример для Visual Studio (конфигурация Win32 / x86).
В C++‑части остаётся лишь ввод/вывод и объявление переменных; вся «работа» по перестановке половин выполняется во встроенном ассемблере (__asm).
cpp// swap_halves_inline_asm.cpp // Меняет местами первую и вторую половины динамического массива целых. // Компилировать как Win32 (x86): cl /EHsc /W4 swap_halves_inline_asm.cpp #include <iostream> #include <cstdlib> #include <ctime> int main() { std::srand(static_cast<unsigned>(std::time(nullptr))); unsigned n; // размер (должен быть чётным) std::cout << "Введите чётный размер массива: "; std::cin >> n; if (n == 0 || (n & 1)) { std::cout << "Размер должен быть положительным и чётным!\n"; return 1; } int* a = new int[n]; // динамический массив /* заполнение случайными числами */ for (unsigned i = 0; i < n; ++i) a[i] = std::rand() % 100; // 0‒99 std::cout << "\nИсходный массив:\n"; for (unsigned i = 0; i < n; ++i) std::cout << a[i] << ' '; std::cout << "\n\n"; /***************************************************************** * Ассемблер: переставляем половины местами * esi –‑ ptr на элемент i (первая половина) * edi –‑ ptr на элемент i+n/2 (вторая половина) * ecx –‑ счётчик = n/2 итераций *****************************************************************/ __asm { mov esi, a ; esi = &a[0] mov ecx, n shr ecx, 1 ; ecx = n/2 (кол-во обменов) ; вычисляем адрес начала второй половины: a + (n/2)*4 mov eax, ecx shl eax, 2 ; eax = (n/2)*sizeof(int) add eax, esi mov edi, eax ; edi = &a[n/2] swap_loop: mov eax, [esi] ; eax = a[i] xchg eax, [edi] ; a[i] <-> a[i+n/2] (в eax теперь старое a[i+n/2]) mov [esi], eax ; записываем в первую половину add esi, 4 ; ++i add edi, 4 loop swap_loop ; пока ecx != 0 } std::cout << "После перестановки половин:\n"; for (unsigned i = 0; i < n; ++i) std::cout << a[i] << ' '; std::cout << '\n'; delete[] a; return 0; }
Регистр | Значение |
---|---|
esi | Текущий элемент из первой половины |
edi | Соответствующий элемент из второй половины |
ecx | Счётчик итераций (n/2 ) — используется командой loop |
eax | Временный регистр для обмена значений (xchg ) |
a + (n/2) * sizeof(int)
.n/2
раз обмениваем пары элементов с помощью xchg
.loop swap_loop
автоматически декрементирует ecx
и прыгает, пока счётчик не станет 0.Важно: inline‑assembler поддерживается только при сборке под x86.
Для x64 необходимо использовать внешние.asm
‑файлы или intrinsics.