Реферат по предмету "Программирование, Базы данных"


Трансляция всех модификаций команд add и cmp

Введение
         Длянаписания пользователем программ на различных языках программи-
    рованиянеобходимо иметь средства их перевода в машинный язык.  Это вы-
    полняютспециальные программы-переводчики, которые называются транслято-
    рами.  Трансляторы для микроЭВМ преобразуют исходнуюпрограмму на  одном
    из языковпрограммирования в некоторую стандартную форму,    называемую
    объектнойпрограммой. Существует три вида трансляторов: ассемблеры, ком-
    пиляторы иинтерпретаторы.
        Транслятор, преобразующий программу, написанную на языке ассембле-
    ра, в машинныйкод,  называется ассемблером.  При написании программы на
    языкеассемблера программист использует мнемонические обозначения машин-
    ных команд иадресов (имена и метки).  В процессе  трансляции ассемблер
    заменяет всемнемонические обозначения (коды команд и имена) их двоичны-
    ми кодами.  Для сокращения текста при повторенииидентичных частей прог-
    раммы в отдельныеязыки ассемблера введены средства написания и обработ-
    ки макрокоманд.Это позволяет программисту определить некоторую последо-
    вательностькоманд как макроопределение, которое обрабатывается макроас-
    семблером(макропроцессором). Последний представляет тексты макроопреде-
    лений ссоответствующими  фактическими  параметрами макровызова  вместо
    макрокоманд впрограмме.
         Простейшийассемблер является однопроходным и преобразует исходную
    программу заодин просмотр. Но при этом возникают трудности, связанные с
    вычислениемадресов имен,  которые определеныпозже.  Этого можно  избе-
    жать,потребовав, чтобы все имена данных были объявлены заранее, а неоп-
    ределенныеадреса заносились в таблицу,  в которуювводятся ссылки  впе-
    ред. Этатаблица либо используется для модификации команды, либо загруз-
    чиком, которыйможет формировать данный адрес во время загрузки.  Однако
    это не всегдаудобно,  поэтому большинство ассемблероввыполняют  в  два
    прохода.
         Основнаяидея двухпроходного ассемблера проста. На первом  проходе
    все символы(имена, метки) собираются в таблицу символов с соответствую-
    щими значениямиадресов,  на втором генерируетсямашинная  программа  на
    основании построеннойна первом проходе таблицы символов.
         Если языкассемблера включает средства макрорасширений, то макроп-
    роцессорреализуется различными способами.  Онможет быть добавлен к ас-
    семблеру какпрепроцессор для выполнения просмотра исходного текста  пе-
    ред первымпроходом ассемблера.  В результате  препроцессирования  полу-
    чаетсяпрограмма на языке ассемблера,  насодержащая макросов.  При этом
    текстымакроопределений, если они есть в исходной программе,  сохраняют-
    ся, а вместомакровызовов подставляются ассемблерные команды из макрооп-
    ределений.  Возможно также объединение макропроцессора спервым проходом
    ассемблера, чтосокращает время трансляции, но удлиняет текст ассемблера.

;█▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█
;█ -----    ТРАНСЛЯЦИЯВСЕХ МОДИФИКАЦИЙ КОМАНДЫ ADD       — █
;█▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█
      .MODEL TINY
      .CODE
      JUMPS
      ORG 100h
begin:
      jmp   general
;┌──────────────────────────────────────┐
;│ Макрос вывода на экран строки stirng │
;└──────────────────────────────────────┘
Wrt   macrostring
      mov   ah,9              ;Функция вывода строки
      lea   dx,string         ;Загружаем адрес строки
      int   21h               ;Вызов прерывания DOS
endm
;┌──────────────────────────────┐
;│ Основная процедура программы │
;└──────────────────────────────┘
general     proc  near
      push  cs                ;Все
      push  cs                ;   сегменты
      push  cs                ;     приравниваем
      pop   ds                ;     к сегменту
      pop   es                ;          кода
      pop   ss                ;(необходимо для строковых операций)
      Wrt   about             ;Вывод информации о программе
; Начинаем разбор строки параметров
      mov   cl,ds:[80h]       ;Получаем длину строки параметров
      sub   ch,ch             ; Обнуляемch
      cmp   cx,2              ; Смотрим длину строки параметров
      jb    source_error            ;Если она меньше двух — нет вх.файла
      mov   di,82h           ; Заносим в DI адресначала поиска
      mov   path1,di          ;Запоминаем адрес входного файла
      mov   al,' '           ; Искать будем до первогопробела
      repnescasb             ;Запускаем цикл поиска
      jne   dest_error        ;Если не нашли значет нет вых. файла
      mov   byte ptr [di-1],0; Приводим к формату ASCIIZ
      mov   path2,di          ;Запоминаем адрес выходного файла
      mov   cl,ds:[80h]       ;Заносим в cl длину строки поиска
      sub   ch,ch             ; Обнуляемch
      mov   al,13             ; Искать будем до символа CR
      repnescasb             ;Запуск цикла поиска
      jne   dest_error        ;Если не нашли значет нет вых. файла
      mov   byte ptr [di-1],0; Приводим к формату ASCIIZ
      call  Fopen             ;Открываем входной файл
      jc    open_source_error; Если ошибка, выдаем сообщение
      call  Fcreate                 ;Создаем выходной файл
      jc    create_dest_error; Если ошибка, выдаем сообщение
gen1:call  Fread             ;Считываем очередную строку из файла
      jc    read_error        ;Переход если ошибка
      cmp   EOF,1             ;Смотрим признак конца файла
      jne   gen2              ;Если не конец, продолжаем
      cmp   si,0              ;Проверяем длину строки
      jne   gen2              ;Если не 0 символов продолжаем
      jmp   read_error        ;Иначе выводим сообщение об ошибке
gen2:inc   string                  ;Увеличиваем счетчик строк
      mov   strlen,si         ;Запоминаем длину строки
      call  DelSpc                  ;Вызываем процедуру удаления пробелов
      cmp   strlen,2          ;Если длина строки 2 символа, то
      je    gen1              ;переходим на чтение следующей
      lea   di,buffer         ;Загружаем адрес строки
      cmp   byte ptr [di],';'; Если первый символ строки; то
      je    gen1              ;переходим на чтение следующей
      lea   si,command        ;Будем искать строку ADD
      mov   cx,3              ;Длина искомой строки 3 символа
      repe  cmpsb             ;Начинаем поиск
      je    gen3              ;Переход, если ADD найдена
      wrt   error06                 ;Вывод сообщения об ошибке
      call  WrtStr                  ;Вывод ошбочной строки
      mov   was_error,1       ;Устанавливаем флаг ошибки
      jmp   gen1              ;Переход на чтение следующей строки
gen3:call  Coding
      cmp   was_error,0
      jne   gen1
      call  Fwrite
      jnc   gen1
      ret
gen4:mov   bx,dest                 ;Если трансляция проведена успешно
      call  Fclose                  ;Закрываем выходной файл
      Wrt   mes2              ;Вывод сообщения о завершении
      Wrt   mes3              ;Вывод сообщения о строках
      call  WrtStr                  ;Вывод числа обработаных строк
      Wrt   mes1              ; ВыводCR,LF
      ret                     ;ВЫХОД В DOS
; Далее располагаются метки перехода по различным ошибкам
source_error:
      Wrt   error01
      ret
dest_error:
      Wrt   error02
      ret
open_source_error:
      Wrt   error03
      ret
create_dest_error:
      Wrt   error04
      ret
read_error:
      cmp   EOF,1             ;Смотрим был ли конец файла
      je    skip_err_message  ; Если да, то это не ошибка
      Wrt   error05                 ;Иначе выводим сообщение об ошибке
      mov   was_error,1       ;Устанавливаем флаг ошибки
skip_err_message:
      mov   bx,source         ;Заносим дескриптор выходного файла
      call  Fclose                  ;Закрываем выходной файл
      cmp   was_error,0       ;Смотрим флаг ошибки
      je    gen4              ;Если ошибок нет, то переход
      call  Fdel              ;Иначе удаляем выходной файл
      Wrt   mes1              ; ВыводCR,LF
      Wrt   bell              ; Выводсигнала
      ret
general     endp
;┌──────────────────────────────────────────────────────┐
;│  ПереводитзначениерегистраAX вдесятичныйформат     │
;└──────────────────────────────────────────────────────┘
Decimal     proc  near
      call  clear             ; Очищаемстрокувывода
      mov   cx,0010                 ; Заносим в CX делитель
      lea   si,outstr+4       ;Указатель на конец строки
b20:  cmp   ax,0010                 ;Сравниваем AX с 10
      jb    shortb30         ; Переход, если меньше
      xor   dx,dx             ;Обнуляем DX
      div   cx                ;Делем AX на CX
      or    dl,30h                  ;Добавляем 48, чтобы получить 1
      mov   [si],dl                 ;Заносим в выходную строку
      dec   si                ;Движемся влево
      jmp   shortb20         ; Переход на следующий символ
b30:  or    al,30h                  ;Добавляем 48, чтобы получить 1
      mov   [si],al                 ;Заносим в выходную строку
      ret
; Вспомогательная процедура. Очищает строку outstr(забивает нулями)
clearproc  near
      lea   si,outstr         ;Загружаем адрес выходной строки
      mov   cl,48             ;48 — символ нуля
      mov   [si],cl                 ;Забиваем
      mov   [si+1],cl         ;    нулями
      mov   [si+2],cl         ;       все
      mov   [si+3],cl         ;         символы
      mov   [si+4],cl         ;            строки
      ret                     ;Выход
clearendp
outstr      db    '     $'
Decimal     endp
;┌──────────────────────────────┐
;│Процедуравыводачисластрок│
;└──────────────────────────────┘
WrtStr      proc  near
      xor   ax,ax             ; ОбнулениерегистраAX
      mov   al,string         ; В AL число обработанных строк
      call  Decimal                 ;Преобразуем в десятичный формат
      Wrt   outstr                  ;Выводим на экран
      ret                     ; Выход
WrtStr      endp
;┌─────────────────────────────┐
;│ Процедура удаления пробелов │
;└─────────────────────────────┘
DelSpc      proc  near
      cld                     ; Устанавливаем флагнаправления
      lea   si,buffer         ;Заносим в SI адрес буфера
      mov   di,si             ;Дублируем в DI
      mov   cx,strlen         ;В CX длина считанной строки
      xor   bx,bx             ;Обнуляем BX
      mov   dl,1              ; Условие цикла
del1:lodsb                   ; Загружаем в AL один байт
      cmp   al,65             ;A?
      jb    del2              ;Переход если меньше
      cmp   al,90             ;Z?
      ja    del2              ;Переход если больше
      add   al,32             ;Иначе перевод F-f
      xor   dl,dl             ;Обнуляем DL
      jmp   del4              ;Переход на запись символа
del2:cmp   al,''                  ; Пробел?
      je    del3              ; Если да, то переход
      xor   dl,dl             ;Обнуляем DL
      jmp   del4              ;Переход на запись символа
del3:cmp   dl,1              ;DL=1?
      je    del5              ;Если да, то переход
      mov   dl,1              ;Заносим в DL 1
del4:stosb                   ; Запись символа в строку
      inc   bx                ;Увеличиваем счетчик символов
del5:loop  del1              ;Цикл
      mov   strlen,bx         ;Заносим длину преобразованной строки
      ret                     ; Выход
DelSpc      endp
;┌──────────────────────────┐
;│ Процедура открытия файла │
;└──────────────────────────┘
Fopenproc  near
      mov   ah,3dh           ; Функция открытия файла
      xor   al,al             ;Открываем на чтение (AL=0)
      mov   dx,path1          ;Адрес ASCIIZ строки файла
      int   21h               ;Вызов прерывания DOS
      jnc   ok1               ;Переход, если открытие успешно
      stc                     ; Установка флага переноса
      ret                     ; Выход
ok1:  mov   source,ax         ;Запоминаем дескриптор файла
      ret                     ; Выход
Fopenendp
;┌──────────────────────────┐
;│ Процедура создания файла │
;└──────────────────────────┘
Fcreate     proc  near
      mov   ah,3ch           ; Функция создания файла
      xor   cx,cx             ;Заносим атрибут файла в CX
      mov   dx,path2          ;Адрес ASCIIZ строки файла
      int   21h               ;Вызов прерывания DOS
      jnc   ok2               ;Переход, если файл создан успешно
      mov   ah,3ch                  ;Если выходной файл не задан
      xor   cx,cx             ;Устанавливаем по умолчанию
      lea   dx,default        ; ИмяOUT.COM
      int   21h               ; Пытаемся создать файл
      jnc   ok2               ;Если получилось — на выход
      stc                     ; Установка флага переноса
      ret                     ; Выход
ok2:  mov   dest,ax                 ;Запоминаем дескриптор файла
      ret                     ;Выход
default     db    'OUT.COM',0
Fcreate     endp
;┌──────────────────────────┐
;│Процедуразакрытияфайла│
;└──────────────────────────┘
Fclose      proc  near
      mov   ah,3eh            ;Функциязакрытияфайла
      int   21h               ; Вызов прерывания DOS
      jnc   ok3               ;Переход, если файл успешно закрыт
      Wrt   error05          ; Вывод сообщения обошибке
ok3:  ret                     ;Выход
Fclose      endp
;┌────────────────────────┐
;│Процедурачтенияфайла│
;└────────────────────────┘
Freadproc  near
      lea   dx,buffer         ; Загружаем адрес буфера
      mov   di,dx             ;Запоминаем адрес начала буфера в DI
      xor   si,si             ;Обнуляем SI
      mov   bx,source         ;Заносим в BX дескриптор файла
      mov   cx,1              ;Число символов для чтения
frd1:mov   ah,3fh                  ;Функция чтения из файла
      int   21h               ;Вызов прерывания DOS
      jnc   frd2              ;Переход, если нет ошибки
      wrt   error05                 ;Вывод сообщения об ошибке
      stc                     ; Устанавливаем флагпереноса
      ret                     ; Выход
frd2:cmp   ax,0              ;Если AX=0, то достигнут конец файла
      je    end1              ;переход на установку флага EOF
      inc   si                ;Увеличиваем счетчик
      cmp   byte ptr [di],10  ; Смотрим не пустая ли строка
      je    frd3              ;Если да, то переход
      inc   dx                ;Увеличиваем адрес буфера
      inc   di                ;Увеличиваем указатель начала буфера
      jmp   frd1              ;Чтение следующего символа
end1:mov   EOF,1             ;Устанавливаем флаг конца файла
frd3:clc                     ; Сброс флага переноса
      ret                     ; Выход
Freadendp
;┌─────────────────────────┐
;│ Процедура записи в файл │
;└─────────────────────────┘
Fwrite      proc  near
      mov   bx,dest                 ;Заносим в BX дескриптор
      lea   dx,cod                  ;Заносим в DX записываемый код
      mov   cx,2              ;Число байт для записи
      mov   ah,40h                  ;Функция записи в файл
      int   21h               ;Вызов прерывания DOS
      jnc   ok4               ;Переход, если нет ошибки
      Wrt   error10                 ;Вывод сообщения об ошибке
ok4:  ret                     ;Выход
Fwrite      endp
;┌──────────────────────────┐
;│Процедураудаленияфайла│
;└──────────────────────────┘
Fdel  proc  near
      mov   dx,path2          ;Путь к удаляемому файлу
      mov   ah,41h                  ;Функция удаления файла
      int   21h               ;Вызов прерывания DOS
      jnc   ok5               ;Переход, если нет ошибки
      lea   dx,defaul2        ;Пробуем удалить OUT.COM
      mov   ah,41h                  ;Функция удаления файла
      int   21h               ;Вызов прерывания DOS
      jnc   ok5               ;Переход, если нет ошибки
      Wrt   error11                 ;Вывод сообщения об ошибке
ok5:  ret                     ;Выход
defaul2     db    'OUT.COM',0
Fdel  endp
;┌────────────────────────────────┐
;│Процедуракодированияоперации│
;└────────────────────────────────┘
Coding      proc  near
      inc   di                ; Увеличиваемуказательвмассиве
      mov   si,di             ; Заносим в SI адрес первогооперанда
      mov   cod,0             ;Обнулаяем код
      mov   numbop,0          ;Номер операнда — первый
      mov   al,','                  ;Будем искать разделитель операндов
      mov   cx,strlen         ;В CX заносим длину строки
      sub   cx,4              ;Вычитаем длину ADD+пробел
      repnescasb             ;Начало поиска
      je    cod1              ;Переход, если разделитель найден
      Wrt   error07                 ;Выдаем сообщение об ошибке
      call  WrtStr                  ;Выводим адрес ошибочной строки
      mov   was_error,1       ;Устанавливаем флаг ошибки
      ret                     ; Выход
cod1:mov   second,di         ;В second адрес второго операнда
      dec   di                ;Смещаем указатель
      dec   di                ;на конец первого операнда
cod2:mov   dx,di             ;Запоминаем адрес конца первого оп.
      sub   dx,si             ;Выч. из адреса конца адрес начала
      inc   dx                ; Увеличиваем на 1
      cmp   dx,2              ;Смотрим длину первого операнда
      je    cod3              ;Если она равна 2, операнд — регистр
      ja    cod8              ;Если больше, операнд — память
      Wrt   error08                 ;Выдаем сообщение об ошибке
      call  WrtStr                  ;Выводим адрес ошибочной строки
      mov   was_error,1       ;Устанавливаем флаг ошибки
      ret                     ; Выход
; --------------------------------------; операнд — регистр
cod3:mov   dx,16             ;Всего 16 регистров. DX — счетчик
      lea   di,Rtable         ;Загружаем адрес таблицы регистров
newreg:     mov   cx,2              ;Сравниваем два символа
      rep   cmpsb             ;Начало сравнения
      je    regfound          ;Переход, если регистр найден
      inc   di                ;Увеличиваем смещение в таблице на 1
      inc   di                ;Увеличиваем смещение в таблице на 1
      dec   si                ;Указатель на начало перв. операнда
      dec   dx                ;Уменьшаем счетчик на 1
      jnz   newreg                  ;Если еще не все регистры, переход
      Wrt   error08                 ;Если регистр не найден — ошибка
      call  WrtStr                  ;Выводим адрес ошибочной строки
      mov   was_error,1       ;Устанавливаем флаг ошибки
      ret                     ; Выход
regfound:
      mov   ah,[di]                 ;Запоминаем код регистра
      cmp   numbop,0          ;Если это первый операнд
      je    cod7              ;То переход на установку d-бита
      cmp   typeop,1          ;Иначе это второй операнд
      je    cod4              ;Переход, если первый оп. имеет тип m
      xor   al,al             ;Иначе оба операнда регистры
      mov   bx,cod                  ;Заносим в BX код операции
      mov   bh,ah             ;Заносим в BH код регистра
      and   bx,0101h          ;Сравниваем w-биты
      cmp   bh,bl             ;Обоих операндов
      je    cod5              ;Если они равны, то переход
      Wrt   error09                 ;Иначе ошибка — несоответствие типов
      call  WrtStr                  ;Выводим адрес ошибочной строки
      mov   was_error,1       ;Устанавливаем флаг ошибки
      ret                     ; Выход
cod4:mov   al,ah             ;Заносим в AL код команды
      and   al,01h                  ;Устанавливаем в 1 w-бит
      and   ah,00111000b            ;Установка битов в поле reg
      jmp   cod6              ;Переход на следующий операнд
cod5:mov   cl,3              ;Будем сдвигать на 3 бита вправо
      shr   ah,cl             ;Сдвигаем код регистра в поле r/m
      or    ah,0c0h                 ;Установка поля mod в 11
                             ;(т.е. биты r/m определяют регистр)
cod6:or    cod,ax                  ;Накладка установленных битов на код
      inc   numbop                  ;Берем второй операнд
      mov   typeop,0          ;Устанавливаем тип операнда r
      jmp   cod11             ;Переход далее
cod7:mov   al,02h                  ;Установка бита направления (d-бит)
      or    al,ah             ;Накладываем на код
      and   ax,0011100000000011b    ; Установка битов в поле reg и r/m
      mov   cod,ax                  ;Заносим полученное в готовый код
      inc   numbop                  ;Увеличиваем номер операнда
      mov   typeop,0          ;Устанавливаем тип операнда r
      jmp   short cod11       ;Переход далее
;---------------------------------------; операнд — память
cod8:cmp   numbop,0          ;Первый операнд?
      je    cod9              ;Если да — переход
      cmp   typeop,1          ;Тип операнда m?
      jne   cod9              ;Если нет — переход
      Wrt   error10                 ;Иначе ошибка: оба операнда — память
      call  WrtStr                  ;Выводим номер ошибочной строки
      mov   was_error,1       ;Устанавливаем флаг ошибки
      ret                     ; Выход
cod9:cmp   byte ptr [si],'['; Операнд начинается со скобки?
      jne   cod10             ;Если нет — переход на ошибку
      cmp   byte ptr [di],']'; Операнд заканчивается скобкой?
      jne   cod10             ;Если нет — переход на ошибку
      inc   si                ;Пропускаем скобку
      dec   di                ;Отодвигаем указатель назад от скобки
      mov   dx,di             ;Заносим в DX конец операнда
      sub   dx,si             ;Вычитаем из конца начало строки
      inc   dx                ;Увеличиваем на 1
                             ;Т.о. в DX — длина операнда
; — Далее идет установка полей mod и r/m---------------------------
      mov   bx,7              ;Всего 7 типов адресации памяти
      lea   di,ExTabl         ;Адрес таблицы способов адресации
rm1:  push  si                ;Запоминаем адрес начала операнда
      mov   cl,[di]                 ;Заносим в CL длину операнда
      xor   ch,ch             ; ОбнуляемCH
      inc   di                ; Двигаем указатель в ExTabl
      cmp   cx,dx             ;Сравниваем длины операндов
      jne   rm2               ;Переход если не равны
      rep   cmpsb             ;Иначе сравниваем на соответствие
      je    rm3               ;Переход если равны
rm2:  inc   di                ;Двигаем указатель в ExTabl на 1
      add   di,cx             ;Теперь сдвигаем его на 5
      pop   si                ;Восст. адрес начала операнда
      dec   bx                ;Уменьшаем счетчик вариантов
      jnz   rm1               ;Если он не равен нулю — переход
      Wrt   error08                 ;Если счетчик равен 0, а соответствий
      call  WrtStr                  ;не найдено, значит ошибка в операнде
      mov   was_error,1       ;Устанавливаем флаг ошибки
      ret                     ; Выход
rm3:  pop   si                ;Восст. адрес начала операнда
      mov   ah,[di]                 ;Заносим в AH код операции
      xor   al,al             ; ОбнуляемAL
      or    cod,ax                  ; Накладываем на код кодоперации
      inc   numbop                  ;Увеличиваем номер операнда
      mov   typeop,1          ;Устанавливаем тип операнда m
      jmp   cod11             ;Переход дальше
cod10:
      Wrt   error08                 ;Выводим сообщение об ошибке
      call  WrtStr                  ;Выводим ошибочную строку
      mov   was_error,1       ;Устанавливаем флаг ошибки
      ret
cod11:      cmp   numbop,1          ;Э


Не сдавайте скачаную работу преподавателю!
Данный реферат Вы можете использовать для подготовки курсовых проектов.

Поделись с друзьями, за репост + 100 мильонов к студенческой карме :

Пишем реферат самостоятельно:
! Как писать рефераты
Практические рекомендации по написанию студенческих рефератов.
! План реферата Краткий список разделов, отражающий структура и порядок работы над будующим рефератом.
! Введение реферата Вводная часть работы, в которой отражается цель и обозначается список задач.
! Заключение реферата В заключении подводятся итоги, описывается была ли достигнута поставленная цель, каковы результаты.
! Оформление рефератов Методические рекомендации по грамотному оформлению работы по ГОСТ.

Читайте также:
Виды рефератов Какими бывают рефераты по своему назначению и структуре.