Ваша настоящая проблема в том, что вы определили метку loop:
дважды.
NASM 2.14.02 выводит красивое сообщение об ошибке:
$ nasm print_hex.asm
print_string.asm:5: error: label `loop' inconsistently redefined
print_hex.asm:19: note: label `loop' originally defined here
Препроцессор %include
Директива работает так же, как в C #include
: источники фактически становятся частью одного и того же файла, разделяя одно и то же пространство имен для символов.
Предположительно, у вас есть более старая версия NASM, которая напечатала безумное и бесполезное сообщение об ошибке. IDK, если это связано с тем, что loop
также является мнемоникой инструкции. Так не должно быть, но трудно представить, чтобы NASM имел такую бесполезную обработку дублирующих меток в любой последней версии. Это довольно распространенная ошибка в рукописном асме, и именно на этом обычно используется NASM. Так что, возможно, у NASM была ошибка, которая пробралась loop
за обычное обнаружение дубликатов и заставила его попытаться потерпеть неудачу.
loop:
устраняет неоднозначность строки как метки, а не строки инструкции для NASM. (Но не YASM: он не позволит использовать loop:
в качестве метки)
Использовать локальные имена меток
.loop:
относится к предыдущей нелокальной метке,Так что это как сокращение для print_hex.loop
и print_string.loop
как в объявлении, так и в использовании.
https://www.nasm.us/doc/nasmdoc3.html#section-3.9
Проверка кода
Кстати, ваш коддовольно раздутыйВам не нужно сохранять / восстанавливать каждый регистр в каждой функции;просто дайте им забить regs.
Кроме того, вы можете конвертировать int-> hex более эффективно, без необходимости добавления шаблона. (Начальная 0x
удобна, но остальное вы можете рассчитать в рег). Кроме того, я не думаю, что ваш код обрабатывает разделение 0..9
против a..f
: эти диапазоны кодов символов ASCII, к сожалению, не соседствуют друг с другом.
См. Как преобразовать числов шестнадцатеричный формат? для простой 32-битной версии вы можете легко портировать на 16-битную, с таблицей подстановки или с условной обработкой 0,9 против a..f. Смотрите также https://codegolf.stackexchange.com/revisions/193842/1 для простой версии с условной ветвью. (Более поздняя версия сохраняет еще больший размер кода с использованием DAS).
Используйте небольшие константы в качестве непосредственных операндов, таких как and al, 0xf
, вместо помещения их в CX. Если хотите, уменьшите указатель с конца буфера, или с помощью шестнадцатеричного числа вы можете использовать вращение, чтобы получить откусывание сверху и генерировать в порядке печати.