GAS LISTING task1.S 			page 1


   1              	/*
   2              	   * Вычисление количества позиций символов для
   3              	   * символьного представления неотрицательного
   4              	   * 32-битового целого числа
   5              	   
   6              	   * Пограмма содержательно эквивалентна программе task1.
   7              	
   8              	   * Ассемблирование:  as -ahlsm=task1.lst --32 -gstabs+ -o task1.o task1.S
   9              	   *
  10              	   * -ahlsm ключи полного листинга
  11              	   * task1.lst - имя ТЕКСТОВОГО файла листинга, описывающего
  12              	   * результат ассемблирования
  13              	
  14              	   * --32 - генерировать 32 разрядные машинные команды
  15              	
  16              	   * -gstabs+ - ключи генерации отладочной информации для от
  17              	
  18              	   * -o task1.o - задание имени выходного ( для команды as -
  19              	   * объектного) файла
  20              	
  21              	   * -o ключ определения имени выходного ( для команды as -
  22              	   * объектного) файла
  23              	
  24              	   * task1.S -  исходный -  входной файл (этот файл)
  25              	   *
  26              	   * Редактирование связей: ld -melf_i386 -o task1-exe-S task1.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 task1-exe-S - задание имени выходного
  41              	   * (для команды ld -  исполняемого) файла
  42              	
  43              	   * -o ключ определения имени выходного
  44              	   * (для команды ld -  исполняемого) файла
  45              	
  46              	   * task1.o - объектный файл (входной для редактора связей l
  47              	
  48              	   * Запуск отладчика: kdbg task1-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 task1.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    # готовим к команде деления idivl
  73      00
  74              	                    # нет аналога в C
  75              	nextdigit:
  76 000b BA000000 	        movl  $0, %edx          # еще готовим, уже в цикле
  76      00
  77              	                                # нет аналога в C
  78              	
  79              	#   Смысл этой подготовки.
  80              	#   Примем, что делим 32 битовое число, размещннное в EAX.
  81              	#   Т.к. команда idivl интерпретирует значения в паре реги
  82              	#   как единое 64 битовое делимое, то перед делением EDX до
  83              	#   0.  После выполнения эта команда
  84              	#   помещает в EDX - остаток, в EAX - частное, что
  85              	#   НАРУШАЕТ ИНТЕРПРЕТАЦИЮ значений пары EDX,EAX. Перед сл
  86              	#   интерпретацию надо восстановить, присвоив EDX значен
  87              	
  88 0010 F73D0800 	        idivl ten        # делим объединенные регистры edx:eax на 10
  88      0000
  89              	                         # частное в  eax, остаток в edx
  90              	
  91 0016 43       	        incl %ebx        # ++counter; счетчик делений + 1
  92              	
  93              	#    две следующие команды соответствуют условному опе
  94              	#    nextdigit;
  95              	
  96 0017 83F800   	        cmpl $0, %eax    # частное > 0 ?
  97 001a 7FEF     	        jg   nextdigit   # ДА, продолжаем
  98              	
  99              	
 100              	/* 
 101              	
 102              	проверка условия в ISA ВСЕГДА выполняется парой команд:
GAS LISTING task1.S 			page 3


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


DEFINED SYMBOLS
             task1.S:57     .data:00000000 n
             task1.S:58     .data:00000004 length
             task1.S:59     .data:00000008 ten
             task1.S:66     .text:00000000 _start
             task1.S:75     .text:0000000b nextdigit

NO UNDEFINED SYMBOLS
