Как заменить код на c++ ассемблерной вставкой?

У меня написана функция на языке C++, нужно заменить ее кодом на ассемблере и оформить ассемблерной вставкой для IDE VS2019, может ли кто-то помочь или подсказать где можно почитать об этом? Функция принимает введённые имя и возраст и вставляет их в список. Ниже приведу сам код.

void insert(Node*& head, const char* name, const char* age) {

Node* newNode = new Node;
strncpy_s(newNode->name, name, 8);
newNode->name[8] = '\0';  // Обеспечиваем корректное завершение строки
strncpy_s(newNode->age, age, 2);
newNode->age[2] = '\0';
newNode->next = nullptr;


if (head == nullptr || strcmp(name, head->name) < 0) {
    // Вставка в начало списка
    newNode->next = head;
    head = newNode;
}
else {
    Node* current = head;
    while (current->next != nullptr && strcmp(name, current->next->name) > 0) {
        current = current->next;
    }
    newNode->next = current->next;
    current->next = newNode;
}

}

Код написанный на ассемблере

void insert(Node*& head, const char* name, const char* age) {
__asm {
    // Входные параметры:
    // head (esi) - указатель на указатель на голову списка
    // name (edx) - указатель на строку имени
    // age (ecx) - указатель на строку возраста

    // Сохраняем текущие значения регистров
    push ebx
    push edi
    push esi
    push edx
    push ecx

    // Получаем указатель на голову списка
    mov esi, [esp + 20]     // head
    mov edx, [esp + 24]     // name
    mov ecx, [esp + 28]     // age

    // Выделяем память для нового узла (Node)
    push 8                   // Размер структуры Node (9 байт для name, 3 для age, 4 для next)
    call malloc             // Вызов malloc
    add esp, 4              // Очистка стека после вызова malloc
    mov ebx, eax            // Новый узел сохраняем в ebx

    // Копируем имя в новый узел (newNode->name)
    lea edi, [ebx]          // edi указывает на новый узел
    lea eax, [edi + 0]      // Адрес поля name в новом узле
    mov ebx, edx            // ebx указывает на строку name
    call strncpy_s         // Копирование строки name
    // Завершаем строку null-символом для name
    lea eax, [edi + 8]
    mov byte ptr[eax], 0

    // Копируем возраст в новый узел (newNode->age)
    lea eax, [edi + 8]      // Адрес поля age в новом узле
    mov ebx, ecx            // ebx указывает на строку age
    call strncpy_s         // Копирование строки age
    // Завершаем строку null-символом для age
    lea eax, [edi + 10]
    mov byte ptr[eax], 0

    // Устанавливаем указатель next в nullptr
    lea eax, [edi + 12]     // Адрес поля next
    mov dword ptr[eax], 0  // newNode->next = nullptr

    // Если список пуст (head == nullptr), вставляем в начало
    mov eax, [esi]          // Загружаем head
    cmp eax, 0              // Если head == nullptr
    je InsertAtStart        // Переход к вставке в начало

    // Если список не пуст, ищем место для вставки
    SearchLoop :
    mov edx, [eax + 0]      // Загружаем имя текущего узла
        lea ecx, [edi + 0]      // Адрес нового имени (name)
        call strcmp             // Сравниваем строки
        jg ContinueSearch       // Если current->name > newNode->name, продолжаем

        // Вставляем узел после текущего
        mov edx, [eax + 4]      // Загружаем указатель на следующий узел
        lea ecx, [edi + 12]     // Адрес next нового узла
        mov[ecx], edx          // newNode->next = current->next
        lea edx, [eax + 4]      // Адрес next текущего узла
        lea ecx, [edi + 12]     // Адрес next нового узла
        mov[edx], ecx          // current->next = newNode

        jmp EndInsert

        ContinueSearch :
    mov eax, [eax + 4]      // Переходим к следующему узлу
        jnz SearchLoop          // Если не конец списка, продолжаем

        InsertAtStart :
    // Вставка в начало списка
    lea eax, [edi + 12]     // Адрес поля next в новом узле
    mov dword ptr[eax], [esi]  // newNode->next = *head
    mov[esi], ebx          // *head = newNode

        EndInsert :
    // Восстанавливаем регистры
    pop ecx
    pop edx
    pop esi
    pop edi
    pop ebx
}

}


Ответы (1 шт):

Автор решения: MBo

mov из памяти в память нельзя делать, используйте промежуточный регистр

mov ecx, dword ptr [esi]
mov dword ptr [eax], ecx
→ Ссылка