В одномерном динамическом массиве целых чисел дли...
Создано: 13 апреля 2025 г.
Создано: 13 апреля 2025 г.
В одномерном динамическом массиве целых чисел длиной в слово четной размерности поменять местами первую половину массива со второй.
• Массив заполнить генератором случайных чисел на C++ и вывести его на экран.
сделай это задание на вкрапленном ассемблере.
Ниже приведён компактный пример для MSVC (x86, 32‑bit) с использованием встроенного ассемблера __asm
.
Он создаёт динамический массив int
чётной длины, заполняет его случайными числами, выводит, а затем полностью меняет местами первую и вторую половины массива на ассемблере.
cpp#include <iostream> #include <cstdlib> #include <ctime> int main() { const int n = 16; // чётная длина (можно заменить на любое чётное число) int* a = new int[n]; // динамический массив std::srand(static_cast<unsigned>(std::time(nullptr))); for (int i = 0; i < n; ++i) // заполняем случайными числами a[i] = std::rand() % 100; std::cout << "Before swap:\n"; for (int i = 0; i < n; ++i) std::cout << a[i] << ' '; std::cout << "\n\n"; /*---------------------------------------------------- Меняем половины местами (инлайн‑ASM, MSVC, x86) ecx = n/2 –‑ количество обменов esi -> начало первой половины edi -> начало второй половины ----------------------------------------------------*/ __asm { mov esi, a ; esi = &a[0] mov ecx, n shr ecx, 1 ; ecx = n/2 (счётчик обменов) mov edi, esi add edi, ecx*4 ; edi = &a[n/2] swap_loop: mov eax, [esi] ; eax = a[i] xchg eax, [edi] ; eax <-> a[i + n/2] mov [esi], eax ; a[i] = прежнее a[i + n/2] add esi, 4 ; ++i add edi, 4 loop swap_loop ; пока ecx != 0 } std::cout << "After swap:\n"; for (int i = 0; i < n; ++i) std::cout << a[i] << ' '; std::cout << '\n'; delete[] a; return 0; }
rand()
заполняет массив.esi
— указатель на текущий элемент первой половины.edi
— указатель на «зеркальный» элемент второй половины.ecx = n/2
— счётчик, одновременно равный количеству требуемых обменов.swap_loop
mov eax, [esi]
– читаем левый элемент.xchg eax, [edi]
– обмениваем его с правым (второй половины).mov [esi], eax
– записываем полученное значение в левую позицию.int
) и повторяем, пока ecx
не станет 0.Важно: MSVC‑style inline assembly поддерживается только в 32‑битных сборках.
Для 64‑битных проектов используйте отдельный.asm
‑файл или GCC‑styleasm
/__attribute__((naked))
.
cpp// ... тот же код генерации массива ... asm volatile( "mov %[ptr], %%rsi\n\t" // rsi = &a[0] "mov %[len], %%rcx\n\t" "shr $1, %%rcx\n\t" // rcx = n/2 "lea (%%rsi,%%rcx,4), %%rdi\n" // rdi = &a[n/2] "1:\n\t" "mov (%%rsi), %%eax\n\t" "xchg %%eax, (%%rdi)\n\t" "mov %%eax, (%%rsi)\n\t" "add $4, %%rsi\n\t" "add $4, %%rdi\n\t" "loop 1b\n\t" : : [ptr]"r"(a), [len]"r"(n) : "rsi", "rdi", "rcx", "rax", "memory" );
Оба варианта делают одно и то же; выберите тот, который подходит вашей среде.