GAS LISTING 1.S 			page 1


   1              	/*
   2              	 * Вычисление количества позиций символов для 
   3              	 * символьного представления неотрицательного 
   4              	 * 32-битового целого числа
   5              	
   6              	 * Пограмма содержательно эквивалентна программе 1.c
   7              	 
   8              	 * Ассемблирование:  as -ahlsm=1.lst --32 -gstabs+ -o 1.o 1.S
   9              	 *	
  10              	 * -ahlsm ключи полного листинга
  11              	 * 1.lst - имя ТЕКСТОВОГО файла листинга, описывающего 
  12              	 * результат ассемблирования
  13              	
  14              	 * --32 - генерировать 32 разрядные машинные команды 
  15              	
  16              	 * -gstabs+ - ключи генерации отладочной информации для отл
  17              	
  18              	 * -o 1.o - задание имени выходного ( для команды as - 
  19              	 * объектного) файла
  20              	
  21              	 * -o ключ определения имени выходного ( для команды as - 
  22              	 * объектного) файла
  23              	
  24              	 * 1.S -  исходный -  входной файл (этот файл)
  25              	 *
  26              	 * Редактирование связей: ld -melf_i386 -o 1-exe-S 1.o
  27              	
  28              	 * МОЖНО НЕ ЧИТАТЬ! В нашем курсе используется только 
  29              	 *	            -melf_i386 
  30              	 *  -m<эмуляция ld> ld может генерировать машинный код 
  31              	 *     исполняемого файла для нескольких архитектур.
  32              	 *     Говорят, что ld "эмулирует" архитектуру.	 
  33              	 *  Поддерживаемые архитектуры - "эмуляции":
  34              	   
  35              	*	elf_x86_64
  36              	*	elf_i386
  37              	*	i386linux
  38              	*	elf_l1om
  39              	
  40              	 * -o 1-exe-S - задание имени выходного  
  41              	 * (для команды ld -  исполняемого) файла 
  42              	
  43              	 * -o ключ определения имени выходного  
  44              	 * (для команды ld -  исполняемого) файла
  45              	
  46              	 * 1.o - объектный файл (входной для редактора связей ld)
  47              	
  48              	 * Запуск отладчика: kdbg 1-exe-S 
  49              	 *
  50              	*/
  51              	 
  52              	.include "my-macro"  # подключение файла с макроопределениями
   1              	/* Макроопределение завершения работы */
   2              	
   3              	.macro Finish
   4              	    movl $0, %ebx 	# first argument: exit code
   5              	    movl $1, %eax 	# sys_exit index
GAS LISTING 1.S 			page 2


   6              	    int  $0x80 		# kernel interrupt
   7              	.endm
   8              	
  53              	
  54              	    
  55              	.data 	# секция данных, распределение памяти
  56              	#               соотв. конструкция языка C и коммент.
  57 0000 29090000 	n: 	.long 2345      # int n = 2345; число
  58 0004 00000000 	length: .long 0         # int length =0; результат
  59 0008 0A000000 	ten: 	.long 10        # определяем константу ЯВНО 
  60              	                        # нет аналога в C  
  61              	
  62              	.text # секция команд процесора 
  63              	
  64              	.global _start 	# точка входа - глобальная метка
  65              	
  66              	_start: 	
  67 0000 90       		nop             # пустая операция - no operation
  68              	
  69              	# нужна, чтобы задать отладчику контр. точку останова н
  70              	# следующей, первой содержательной команде программы
  71              	
  72 0001 BB000000 	        movl $0, %ebx   # counter = 0; счетчик делений
  72      00
  73 0006 A1000000 		movl n, %eax    # готовим деление  
  73      00
  74              	                        # нет аналога в C
  75              	nextdigit:
  76 000b BA000000 	        movl  $0, %edx          # еще готовим 
  76      00
  77              	                                # нет аналога в C
  78              	# команда idivl делит 64-битовое целое на свой операнд
  79              	# младшие разряды делителя фиксированы в %eax, старшие
  80              	# в %edx. После деления частное в %eax, остаток в %edx
  81              	# Т.к. наше число 32-битовое перед каждым делением нужно
  82              	# присвоить регистру %edx значение нуль (см. предыдущую 
  83              	# команду - movl  $0, %edx  )
  84              	
  85 0010 F73D0800 	        idivl ten      # делим объединенные регистры edx:eax на 10
  85      0000
  86              	                       # частное в  eax, остаток в edx
  87              	        
  88 0016 43       	        incl %ebx       # ++counter; счетчик делений + 1
  89              	
  90              	#  две следующие команды соответствуют условному 
  91              	#  оператору if (quotient) goto nextdigit;
  92              	
  93 0017 83F800   	        cmpl $0, %eax    # частное < 0 ?
  94 001a 7FEF     	        jg   nextdigit   # НЕТ, продолжаем
  95              	
  96              	
  97              	/* проверка условия на ЯКЦП ВСЕГДА выполняется парой к
  98              	
  99              	cmp <операнд1>, <операнд2> - вып. вычитание <операнд2>-<опера
 100              	                        - отражает знак и др. свойства результата
 101              	                          в битах регистра флагов.
 102              	
GAS LISTING 1.S 			page 3


 103              	 jcc <операнд> - j[ump on] c[ondition] c[ode] проверяет
 104              	        условие в битах регистра флагов и по результату п
 105              	        выполняет/не выполняет переход  по адресу <операн
 106              	
 107              	 В нашем случае команда jg   nextdigit { jg - jump if greater
 108              	- перейти если строго  больше} выполняет переход на мет
 109              	nextdigit: если предыдущая команда cmpl $0, %eax установила в
 110              	регистре флагов биты, указывающие, что значение в реги
 111              	т.е. частное, СТРОГО  БОЛЬШЕ нуля.
 112              	*/
 113              	
 114 001c 891D0400 	        movl %ebx, length  # length = counter; ДА,сохраняем результат 
 114      0000
 115              	
 116              		Finish            # конец работы, 
 116 0022 BB000000 	> movl $0,%ebx
 116      00
 116 0027 B8010000 	> movl $1,%eax
 116      00
 116 002c CD80     	> int $0x80
 117              	                          # возврат в ОС
 118              	                          # (макро из файла my-macro)
 119              	        
 120              	.end   # последняя строка исходного текста
GAS LISTING 1.S 			page 4


DEFINED SYMBOLS
                 1.S:57     .data:0000000000000000 n
                 1.S:58     .data:0000000000000004 length
                 1.S:59     .data:0000000000000008 ten
                 1.S:66     .text:0000000000000000 _start
                 1.S:75     .text:000000000000000b nextdigit

NO UNDEFINED SYMBOLS
