Online Compiler Nasm

global main extern scanf extern printf section .data in_fmt db " %c%c %c%c", 0 out_fmt db "%d", 10, 0 section .bss x1 resd 1 y1 resd 1 x2 resd 1 y2 resd 1 section .text main: push y2 push x2 push y1 push x1 push in_fmt call scanf add esp,20 movzx eax, byte [x1] sub eax,'A' add eax,1 mov [x1],eax movzx eax, byte [y1] sub eax,'0' mov [y1],eax movzx eax, byte [x2] sub eax,'A' add eax,1 mov [x2],eax movzx eax, byte [y2] sub eax,'0' mov [y2],eax mov eax,[x1] sub eax,[x2] mov edx,eax sar edx,31 xor eax,edx sub eax,edx mov ebx,[y1] sub ebx,[y2] mov edx,ebx sar edx,31 xor ebx,edx sub ebx,edx add eax,ebx push eax push out_fmt call printf add esp,8 xor eax,eax ret
Этот код считывает две шахматные координаты (например, "A1 B2") и вычисляет расстояние между ними по правилу "манхэттенского расстояния" — сумму модулей разностей по горизонтали и вертикали. Сначала буквы преобразуются в числа (A=1, B=2, ...), цифры остаются как есть, затем вычисляется |x1-x2| + |y1-y2|.

- В формате scanf используется " %c%c %c%c" — это считывает четыре отдельных символа, но в памяти они располагаются последовательно. Однако переменные x1, y1, x2, y2 объявлены как dword (4 байта), а scanf записывает только один байт в каждый адрес. Это может привести к тому, что последующие байты остаются мусором, и при загрузке через movzx eax, byte [x1] вы берете только первый байт — это работает, но неэффективно. Проблема в том, что после преобразования вы сохраняете результат обратно в ту же переменную (mov [x1],eax), но теперь это 4-байтовое значение, а не символ. Это нормально, но убедитесь, что вы не путаете размеры.

- После вычисления модуля разности по x (eax) и по y (ebx) вы складываете их и выводите. Код в целом логичен, но есть одна тонкость: при вводе символов через scanf с форматом %c пробел перед первым %c нужен, чтобы пропустить возможный перевод строки. Однако если пользователь вводит строку без лишних пробелов, это работает.