Ассемблер
Как в ассемблере преобразовать строку в число
Чтобы в ассемблере преобразовать строку в число, строку читают посимвольно. Для каждой цифры проверяют, что символ находится между '0' и '9', затем превращают символ в цифру вычитанием '0' и обновляют результат по формуле: result = result * 10 + digit
Идея алгоритма
Для строки:
"123"
алгоритм идет так:
result = 0
result = 0 * 10 + 1
result = 1 * 10 + 2
result = 12 * 10 + 3
В конце получается 123
Почему нужно вычитать ‘0’
Символ '5' — это не число 5, а код символа. В ASCII цифры идут подряд:
'0' -> 48
'1' -> 49
'2' -> 50
...
'9' -> 57
Чтобы получить числовую цифру, делают:
sub al, '0'
Если в al был символ '5', после вычитания получится число 5
Псевдокод на ассемблерной логике
result = 0
loop:
al = [rsi]
if al == 0: done
if al < '0': error
if al > '9': error
al = al - '0'
result = result * 10 + al
rsi = rsi + 1
jump loop
В реальном коде result обычно хранится в регистре вроде rax или eax, адрес строки — в rsi, текущий символ — в al
Пример фрагмента в NASM-стиле
xor eax, eax ; result = 0
next_digit:
mov bl, [rsi] ; взять символ
cmp bl, 0
je done
cmp bl, '0'
jb error
cmp bl, '9'
ja error
sub bl, '0'
imul eax, eax, 10
add eax, ebx
inc rsi
jmp next_digit
Это учебный фрагмент: в реальной программе нужно аккуратно следить за размерами регистров и очисткой старших битов
Что делать с минусом
Если строка может быть отрицательной, сначала проверьте первый символ:
если первый символ '-':
запомнить знак
перейти к следующему символу
После преобразования можно сделать число отрицательным. Но для первого упражнения лучше начать только с положительных чисел
Как проверять ошибки
Нужно обработать три ситуации:
- пустая строка;
- символ не цифра;
- переполнение результата.
Переполнение сложнее всего. Для учебного кода можно ограничить ввод небольшими числами. Для надежного кода нужно проверять, не выходит ли result * 10 + digit за пределы регистра
Частые ошибки
Складывают коды символов
Если не вычесть '0', получится не число, а сумма ASCII-кодов
Не проверяют конец строки
Нужно знать, где остановиться: нулевой байт, длина буфера или перевод строки
Не очищают регистры
Если используете bl, ebx, rax, следите за старшими битами и соглашениями вызова
Что почитать дальше по ассемблеру
Если нужен общий маршрут по теме, откройте рубрику ассемблеру. Для соседних задач пригодятся эти разборы:
- Как вывести число в ассемблере
- CMP в ассемблере
- CMP в ассемблере: как работает сравнение
- CMP, JMP, JE, JNZ: условия и циклы в ассемблере
Как проверить результат на практике
Для ассемблера важно сначала понять, под какую среду написан пример: DOSBox/TASM, Linux x64/NASM, Visual Studio/MASM или микроконтроллер. Один и тот же смысл может записываться разным синтаксисом, поэтому не переносите команды между средами вслепую. Создайте отдельную папку для примера, сохраните файл с расширением .asm, выполните сборку именно тем инструментом, который указан в уроке, и сравните вывод или состояние регистров с ожидаемым результатом
Если пример не собирается, читайте первую ошибку ассемблера: обычно она указывает на строку, неизвестную инструкцию, неверную метку, неправильную секцию или конфликт синтаксиса. Исправляйте одну ошибку за раз. В ассемблере это особенно важно, потому что маленькая опечатка в метке, регистре или размере операнда может полностью изменить поведение программы