Online Compiler Nasm

extern fopen, fclose, fscanf, fprintf, malloc, free section .data input_name db "input.txt", 0 output_name db "output.txt", 0 mode_read db "r", 0 mode_write db "w", 0 fmt_in db "%d", 0 fmt_first db "%d", 0 fmt_next db " %d", 0 section .text global main main: push ebp mov ebp, esp push ebx push esi push edi sub esp, 28 xor esi, esi mov dword [esp], input_name mov dword [esp+4], mode_read call fopen mov ebx, eax read_loop: mov dword [esp], ebx mov dword [esp+4], fmt_in lea eax, [ebp-16] mov dword [esp+8], eax call fscanf cmp eax, 1 jne read_end mov dword [esp], 8 call malloc mov edx, eax mov eax, [ebp-16] mov [edx], eax mov dword [edx+4], 0 cmp esi, 0 je insert_head cmp eax, [esi] jl insert_head mov ecx, esi find_place: mov edi, [ecx+4] cmp edi, 0 je insert_after cmp eax, [edi] jl insert_after mov ecx, edi jmp find_place insert_head: mov [edx+4], esi mov esi, edx jmp read_loop insert_after: mov edi, [ecx+4] mov [edx+4], edi mov [ecx+4], edx jmp read_loop read_end: mov dword [esp], ebx call fclose mov dword [esp], output_name mov dword [esp+4], mode_write call fopen mov ebx, eax mov edi, esi mov dword [ebp-20], 1 print_loop: cmp edi, 0 je print_end cmp dword [ebp-20], 1 jne print_next mov dword [esp], ebx mov dword [esp+4], fmt_first mov eax, [edi] mov dword [esp+8], eax call fprintf mov dword [ebp-20], 0 jmp print_advance print_next: mov dword [esp], ebx mov dword [esp+4], fmt_next mov eax, [edi] mov dword [esp+8], eax call fprintf print_advance: mov edi, [edi+4] jmp print_loop print_end: mov dword [esp], ebx call fclose free_loop: cmp esi, 0 je finish mov edi, [esi+4] mov dword [esp], esi call free mov esi, edi jmp free_loop finish: xor eax, eax add esp, 28 pop edi pop esi pop ebx mov esp, ebp pop ebp ret
Этот код читает целые числа из файла input.txt, строит из них связный список, отсортированный по возрастанию, и записывает результат в output.txt. В конце память освобождается.

- В коде есть ошибка при сравнении чисел для вставки в список. Когда вы сравниваете `eax` (новое число) с `[esi]` (первый элемент списка), вы используете `jl` для перехода к `insert_head`. Но если список пуст (`esi == 0`), вы уже обработали этот случай ранее. Если список не пуст, то при `eax < [esi]` вы вставляете в голову, иначе ищете место. Однако в цикле `find_place` вы сравниваете `eax` с `[edi]` и переходите к `insert_after`, если `eax < [edi]`. Но что, если `eax` больше или равно? Вы переходите к следующему узлу. Проблема в том, что когда вы доходите до конца списка (`edi == 0`), вы переходите к `insert_after`, но `insert_after` пытается прочитать `[ecx+4]` и записать туда новый узел. Это корректно, если `ecx` — последний узел. Однако проверьте, что происходит, когда `edi == 0` и вы переходите к `insert_after`: вы используете `mov edi, [ecx+4]`, но `[ecx+4]` уже равно 0, и вы записываете `[edx+4], edi` (то есть 0), а затем `[ecx+4], edx`. Это правильно для вставки в конец. Но есть другая проблема: когда вы вставляете в середину, вы не обновляете указатель `esi` на голову, если вставка происходит не в голову. Это нормально, так как голова не меняется. Однако есть ошибка в логике сравнения: вы используете `jl` для перехода, когда новое число меньше. Но если числа равны? Сейчас при равенстве `eax` и `[edi]` условие `jl` не