Online Compiler Nasm

extern fopen extern fread extern fwrite extern fclose section .bss array resd 1000000 ; реально прочитано чисел n_elements resd 1 ; итоговый ответ ans_val resd 1 file_ptr resd 1 min_flag resd 1 max_flag resd 1 section .data ; строки для открытия входного файла file_in db "input.bin", 0 mode_r db "rb", 0 ; строки для открытия выходного файла file_out db "output.bin", 0 mode_w db "wb", 0 section .text global main main: ; выравнивание стека push ebp mov ebp, esp and esp, -16 ; fopen("input.bin", "rb") sub esp, 8 push mode_r push file_in call fopen mov [file_ptr], eax ; fread(array, 4, 1000000, file_ptr) ; стек уже выровнен, кладем 4 аргумента = 16 байт push dword [file_ptr] ; аргумент 4 файл push 1000000 ; аргумент 3 макс колво push 4 ; аргумент 2 размер 1 элемента push array ; аргумент 1 куда писать call fread add esp, 16 mov [n_elements], eax ; сколько реально прочитано чисел ; fclose(file_ptr) sub esp, 12 push dword [file_ptr] call fclose add esp, 16 mov dword [min_flag], 1 mov dword [max_flag], 1 mov esi, 0 ; счетчик i (0..n-1) mov ecx, [n_elements] ; ecx - размер массива n .loop_start: cmp esi, ecx jge .loop_end ; i >= n выходим из цикла ;выходим если 2 флага стали нулями mov eax, dword [min_flag] or eax, dword [max_flag] jz .loop_end ; проверка левого ребенка 2*i+1 mov ebx, esi shl ebx, 1 inc ebx cmp ebx, [n_elements] ;если ebx >= n jge .loop_end mov eax, [array + esi * 4] ;eax - родитель cmp eax, [array + ebx * 4] jle .max_L mov [min_flag], 0 ;родитель больше левого ребенка .max_L: cmp eax, [array + ebx * 4] jge .min_R mov [max_flag], 0 ;родитель меньше левого ребенка ;проверка правого ребенка .min_R: inc ebx cmp eax, [array + ebx * 4] jle .max_R ;родитель больше правого ребенка mov [min_flag], 0 .max_R: cmp eax, [array + ebx * 4] jge .fin ;родитель меньше правого ребенка mov [max_flag], 0 .fin: inc esi jmp .loop_start .min_false: ;неубывающая mov [min_flag], 0 jmp .loop_end .max_false: ;невозрастающая mov [max_flag], 0 jmp .loop_end .loop_end: cmp [min_flag], 0 je .print_min cmp [max_flag], 0 je .print_max .print_min: ; неубывающая mov [ans_val], 1 jmp .write_file .print_max: ; невозрастающая mov [ans_val], -1 jmp .write_file .write_file: ; fopen("output.txt", "wb") sub esp, 8 push mode_w push file_out call fopen add esp, 16 mov [file_ptr], eax ; fwrite(ans_val, 4, 1, file_ptr) push file_ptr push 1 push 4 push ans_val call fwrite add esp, 16 ; fclose(file_ptr) sub esp, 12 push dword [file_ptr] call fclose add esp, 16 xor eax, eax mov esp, ebp pop ebp ret
Вот разбор вашего кода:

**1) Что делает код:**
Программа читает из бинарного файла `input.bin` массив 32-битных целых чисел (до 1 000 000 элементов), затем проверяет, является ли этот массив **кучей** (heap). А именно — для каждого элемента (кроме листьев) проверяется свойство «родитель ≥ детей» (невозрастающая куча) или «родитель ≤ детей» (неубывающая куча). В зависимости от результата в файл `output.bin` записывается:  
- `1` — если массив является **неубывающей** кучей (min-heap)  
- `-1` — если массив является **невозрастающей** кучей (max-heap)  
- Если ни то, ни другое — флаги обнуляются, но код не записывает ответ (это потенциальная ошибка).

**2) Конкретные подсказки:**
- **Ошибка с выходными данными:** Если массив **не является ни min-кучей, ни max-кучей**, оба флага `min_flag` и `max_flag` станут равны 0, и программа не запишет никакого ответа в файл. Нужно предусмотреть случай, когда оба флага ложны (например, записать `0`).
- **Потенциальный выход за границы массива:** При проверке правого ребенка (`inc ebx`) вы не проверяете, что `ebx < n_elements`. Если у элемента есть левый ребенок, но нет правого, произойдет чтение за пределами массива. Добавьте проверку `cmp ebx, [n_elements]` перед обращением к `array + ebx*4`.