/*
 * Вычисление количества позиций символов для 
 * символьного представления неотрицательного 
 * 32-битового целого числа

 * Пограмма содержательно эквивалентна программе 1.c
 
 * Ассемблирование:  as -ahlsm=1.lst --32 -gstabs+ -o 1.o 1.S
 *	
 * -ahlsm ключи полного листинга
 * 1.lst - имя ТЕКСТОВОГО файла листинга, описывающего 
 * результат ассемблирования

 * --32 - генерировать 32 разрядные машинные команды 

 * -gstabs+ - ключи генерации отладочной информации для отладчика

 * -o 1.o - задание имени выходного ( для команды as - 
 * объектного) файла

 * -o ключ определения имени выходного ( для команды as - 
 * объектного) файла

 * 1.S -  исходный -  входной файл (этот файл)
 *
 * Редактирование связей: ld -melf_i386 -o 1-exe-S 1.o

 * МОЖНО НЕ ЧИТАТЬ! В нашем курсе используется только 
 *	            -melf_i386 
 *  -m<эмуляция ld> ld может генерировать машинный код 
 *     исполняемого файла для нескольких архитектур.
 *     Говорят, что ld "эмулирует" архитектуру.	 
 *  Поддерживаемые архитектуры - "эмуляции":
   
*	elf_x86_64
*	elf_i386
*	i386linux
*	elf_l1om

 * -o 1-exe-S - задание имени выходного  
 * (для команды ld -  исполняемого) файла 

 * -o ключ определения имени выходного  
 * (для команды ld -  исполняемого) файла

 * 1.o - объектный файл (входной для редактора связей ld)

 * Запуск отладчика: kdbg 1-exe-S 
 *
*/
 
.include "my-macro"  # подключение файла с макроопределениями

    
.data 	# секция данных, распределение памяти
#               соотв. конструкция языка C и коммент.
n: 	.long 2345      # int n = 2345; число
length: .long 0         # int length =0; результат
ten: 	.long 10        # определяем константу ЯВНО 
                        # нет аналога в C  

.text # секция команд процесора 

.global _start 	# точка входа - глобальная метка

_start: 	
	nop             # пустая операция - no operation

# нужна, чтобы задать отладчику контр. точку останова на 
# следующей, первой содержательной команде программы

        movl $0, %ebx   # counter = 0; счетчик делений
	movl n, %eax    # готовим деление  
                        # нет аналога в C
nextdigit:
        movl  $0, %edx          # еще готовим 
                                # нет аналога в C
# команда idivl делит 64-битовое целое на свой операнд
# младшие разряды делителя фиксированы в %eax, старшие
# в %edx. После деления частное в %eax, остаток в %edx
# Т.к. наше число 32-битовое перед каждым делением нужно
# присвоить регистру %edx значение нуль (см. предыдущую 
# команду - movl  $0, %edx  )

        idivl ten      # делим объединенные регистры edx:eax на 10
                       # частное в  eax, остаток в edx
        
        incl %ebx       # ++counter; счетчик делений + 1

#  две следующие команды соответствуют условному 
#  оператору if (quotient) goto nextdigit;

        cmpl $0, %eax    # частное < 0 ?
        jg   nextdigit   # НЕТ, продолжаем


/* проверка условия на ЯКЦП ВСЕГДА выполняется парой команд:

cmp <операнд1>, <операнд2> - вып. вычитание <операнд2>-<операнд1>
                        - отражает знак и др. свойства результата
                          в битах регистра флагов.

 jcc <операнд> - j[ump on] c[ondition] c[ode] проверяет
        условие в битах регистра флагов и по результату проверки
        выполняет/не выполняет переход  по адресу <операнд>.

 В нашем случае команда jg   nextdigit { jg - jump if greater
- перейти если строго  больше} выполняет переход на метку
nextdigit: если предыдущая команда cmpl $0, %eax установила в
регистре флагов биты, указывающие, что значение в регистре %eax,
т.е. частное, СТРОГО  БОЛЬШЕ нуля.
*/

        movl %ebx, length  # length = counter; ДА,сохраняем результат 

	Finish            # конец работы, 
                          # возврат в ОС
                          # (макро из файла my-macro)
        
.end   # последняя строка исходного текста
       # as прекращает чтение файла исходного текста
