Online Compiler Nasm

extern printf, strstr, strlen, fgets, stdin section .bss s1 resb 102 ; 100 символов + \0 + \n s2 resb 102 section .data my_str db "%s", 0 my_bracket_open db "[", 0 my_bracket_close db "]", 0 my_newline db `\n`, 0 section .text global main my_fgets: ; добавил fgets заместо scanf push ebp mov ebp, esp push ebx and esp, -16 ; добавил выравнивание по 16 mov ebx, [ebp + 8] sub esp, 4 push dword [stdin] push 102 push ebx call fgets add esp, 16 sub esp, 12 push ebx call strlen add esp, 16 test eax, eax jz end_fgets cmp byte [ebx + eax - 1], 10 jne end_fgets mov byte [ebx + eax - 1], 0 end_fgets: lea esp, [ebp - 4] pop ebx pop ebp ret printer: push ebp mov ebp, esp push ebx push esi push edi and esp, -16 mov esi, [ebp + 8] mov edi, [ebp + 12] mov ebx, [ebp + 16] movzx eax, byte [ebx] push eax mov byte [ebx], 0 sub esp, 4 push esi push my_str call printf add esp, 12 pop eax mov byte [ebx], al sub esp, 12 push my_bracket_open call printf add esp, 16 sub esp, 8 push edi push my_str call printf add esp, 16 sub esp, 12 push my_bracket_close call printf add esp, 16 sub esp, 12 push edi call strlen add esp, 16 add ebx, eax sub esp, 8 push ebx push my_str call printf add esp, 16 sub esp, 12 push my_newline call printf add esp, 16 lea esp, [ebp - 12] pop edi pop esi pop ebx pop ebp ret main: push ebp mov ebp, esp and esp, -16 sub esp, 12 push s1 call my_fgets add esp, 16 sub esp, 12 push s2 call my_fgets add esp, 16 sub esp, 8 push s1 push s2 call strstr add esp, 16 test eax, eax jz reverse_s1s2 sub esp, 4 push eax push s1 push s2 call printer add esp, 16 jmp finish reverse_s1s2: sub esp, 8 push s2 push s1 call strstr add esp, 16 test eax, eax jz nothing sub esp, 4 push eax push s2 push s1 call printer add esp, 16 jmp finish nothing: sub esp, 8 push s1 push my_str call printf add esp, 16 sub esp, 12 push my_newline call printf add esp, 16 finish: xor eax, eax mov esp, ebp pop ebp ret
Этот код на NASM32 читает две строки со стандартного ввода, затем ищет, является ли одна строка подстрокой другой. Если s2 содержится в s1, то выводит s1, затем в квадратных скобках s2, затем остаток s1 после s2. Если s1 содержится в s2, то делает то же самое, но с переставленными аргументами. Если ни одна не является подстрокой другой, просто выводит s1.

- В функции printer есть проблема с выравниванием стека перед вызовом printf. После того как вы сохранили регистры и выровняли стек, вы делаете `push eax` (4 байта), затем `sub esp, 4` (ещё 4), потом `push esi` и `push my_str` — итого 12 байт аргументов, но стек не выровнен по 16. Проверьте, сколько байт вы добавляете в стек перед каждым вызовом printf, и убедитесь, что общее смещение кратно 16.

- В функции printer после вызова strlen вы делаете `add ebx, eax`, но ebx изначально указывает на начало строки, переданной третьим аргументом. После этого вы пытаетесь напечатать остаток строки, начиная с ebx. Однако если третьим аргументом была строка s1 или s2, то после добавления длины подстроки вы получите указатель на символ после подстроки — это правильно. Но убедитесь, что вы не портите значение ebx до этого момента, так как он используется и для временного сохранения байта.