Ремонт принтеров, сканнеров, факсов и остальной офисной техники


назад Оглавление вперед




[152]

Первым аргументом make-machine является список имен регистров. Второй аргумент - таблица (список двухэлементных списков), связывающая каждое имя операции с процедурой Scheme, которая эту операцию реализует (то есть порождает тот же результат на тех же входных значениях). Последний аргумент описывает контроллер в виде списка из меток и машинных команд, как в разделе 5.1.

Чтобы вычислить НОД двух чисел с помощью этой машины, мы заносим значения во входные регистры, запускаем машину, а когда имитация ее работы завершается, считываем результат:

(set-register-contents! gcd-machine a 206) done

(set-register-contents! gcd-machine b 40) done

(start gcd-machine) done

(get-register-contents gcd-machine a) 2

Эта модель будет работать значительно медленнее, чем процедура gcd, написанная на Scheme, поскольку она имитирует низкоуровневые команды машины, например, assign, с помощью значительно более сложных операций.

Упражнение 5.7.

Проверьте на имитаторе машины, построенные Вами в упражнении 5.4.

5.2.1 Модель машины

Модель машины, которую порождает make-machine, представляется в виде процедуры с внутренним состоянием при помощи методов передачи сообщений, разработанных в главе 3. При построении модели make-machine прежде всего вызывает процедуру make-new-machine, порождающую те части модели, которые у всех регистровых машин одинаковые. Эта базовая модель машины, создаваемая make-new-machine, является, в сущности, контейнером для нескольких регистров и стека, а кроме того, содержит механизм выполнения, который обрабатывает команды контроллера одну за другой.

Затем make-machine расширяет эту базовую модель (посылая ей сообщения) и добавляет в нее регистры, операции и контроллер для конкретной определяемой машины. Сначала она выделяет в новой машине по регистру на каждое из данных имен регистров и встраивает в нее указанные операции. Затем она с помощью ассемблера (assembler) (описанного в разделе 5.2.2) преобразует список контроллера в команды новой машины и устанавливает их ей в качестве последовательности команд. В качестве результата make-machine возвращает модифицированную модель машины.

(define (make-machine register-names ops controller-text) (let ((machine (make-new-machine))) (for-each (lambda (register-name)

((machine allocate-register) register-name))


register-names) ((machine install-operations) ops) ((machine install-instruction-sequence)

(assemble controller-text machine)) machine))

Регистры

Мы будем представлять регистры в виде процедур с внутренним состоянием, как в главе 3. Процедура make-register создает регистр. Регистр содержит значение, которое можно считать или изменить.

(define (make-register name)

(let ((contents *unassigned*)) (define (dispatch message)

(cond ((eq? message get) contents) ((eq? message set)

(lambda (value) (set! contents value))) (else

(error "Неизвестная операция -- REGISTER" message)))) dispatch))

Для доступа к регистрам используются следующие процедуры:

(define (get-contents register) (register get))

(define (set-contents! register value) ((register set) value))

Стек

Стек также можно представить в виде процедуры с внутренним состоянием. Процедура make-stack создает стек, внутреннее состояние которого состоит из списка элементов на стеке. Стек принимает сообщение push, кладущее элемент на стек, сообщение pop, снимающее со стека верхний элемент и возвращающее его, и сообщение initialize, которое дает стеку начальное пустое значение.

(define (make-stack)

(let ((s ()))

(define (push x)

(set! s (cons x s))) (define (pop)

(if (null? s)

(error "Пустой стек -- POP") (let ((top (car s))) (set! s (cdr s))

top)))

(define (initialize)

(set! s ())

done)

(define (dispatch message)

(cond ((eq? message push) push)


((eq? message pop) (pop)) ((eq? message initialize) (initialize)) (else (error "Неизвестная операция -- STACK" message))))

dispatch))

Для доступа к стеку используются следующие процедуры:

(define (pop stack) (stack pop))

(define (push stack value) ((stack push) value))

Базовая машина

Процедура make-new-machine, приведенная на рисунке 5.13, порождает объект, внутреннее состояние которого состоит из стека, изначально пустой последовательности команд, списка операций, где с самого начала присутствует операция инициализации стека, а также таблицы регистров (register table), в которой изначально содержатся два регистра, flag и pc (от program counter, «счетчик программы»). Внутренняя процедура allocate-register добавляет в таблицу новый элемент, а внутренняя процедура lookup-register ищет регистр в таблице.

Регистр flag используется для управления переходами в имитируемой машине. Команды test присваивают ему результат теста (истину или ложь). Команды branch определяют, нужно ли делать переход, в зависимости от значения регистра flag.

Регистр pc определяет порядок выполнения команд при работе машины. Этот порядок реализуется внутренней процедурой execute. В нашей имитационной модели каждая команда является структурой данных, в которой есть процедура без аргументов, называемая исполнительная процедура команды (instruction execution procedure). Вызов этой процедуры имитирует выполнение команды. Во время работы модели pc указывает на часть последовательности команд, начинающуюся со следующей подлежащей исполнению команды. Процедура execute считывает эту команду, выполняет ее при помощи вызова исполнительной процедуры, и повторяет этот процесс, пока имеется команды для выполнения (то есть пока pc не станет указывать на конец последовательности команд).

В процессе работы каждая исполнительная процедура изменяет pc и указывает, какую следующую команду надо выполнить. Команды branch и goto присваивают регистру pc значение, указывающее на новый адрес. Все остальные команды просто продвигают pc так, чтобы он указывал на следующую команду в последовательности. Заметим, что каждый вызов execute снова зовет execute, но это не приводит к бесконечному циклу, поскольку запуск исполнительной процедуры команды изменяет содержимое pc.

Make-new-machine возвращает процедуру dispatch, которая дает доступ к внутреннему состоянию на основе передачи сообщений. Запуск машины осуществляется путем установки pc в начало последовательности команд и вызова execute.

Ради удобства мы предоставляем альтернативный процедурный интерфейс



[стр.Начало] [стр.1] [стр.2] [стр.3] [стр.4] [стр.5] [стр.6] [стр.7] [стр.8] [стр.9] [стр.10] [стр.11] [стр.12] [стр.13] [стр.14] [стр.15] [стр.16] [стр.17] [стр.18] [стр.19] [стр.20] [стр.21] [стр.22] [стр.23] [стр.24] [стр.25] [стр.26] [стр.27] [стр.28] [стр.29] [стр.30] [стр.31] [стр.32] [стр.33] [стр.34] [стр.35] [стр.36] [стр.37] [стр.38] [стр.39] [стр.40] [стр.41] [стр.42] [стр.43] [стр.44] [стр.45] [стр.46] [стр.47] [стр.48] [стр.49] [стр.50] [стр.51] [стр.52] [стр.53] [стр.54] [стр.55] [стр.56] [стр.57] [стр.58] [стр.59] [стр.60] [стр.61] [стр.62] [стр.63] [стр.64] [стр.65] [стр.66] [стр.67] [стр.68] [стр.69] [стр.70] [стр.71] [стр.72] [стр.73] [стр.74] [стр.75] [стр.76] [стр.77] [стр.78] [стр.79] [стр.80] [стр.81] [стр.82] [стр.83] [стр.84] [стр.85] [стр.86] [стр.87] [стр.88] [стр.89] [стр.90] [стр.91] [стр.92] [стр.93] [стр.94] [стр.95] [стр.96] [стр.97] [стр.98] [стр.99] [стр.100] [стр.101] [стр.102] [стр.103] [стр.104] [стр.105] [стр.106] [стр.107] [стр.108] [стр.109] [стр.110] [стр.111] [стр.112] [стр.113] [стр.114] [стр.115] [стр.116] [стр.117] [стр.118] [стр.119] [стр.120] [стр.121] [стр.122] [стр.123] [стр.124] [стр.125] [стр.126] [стр.127] [стр.128] [стр.129] [стр.130] [стр.131] [стр.132] [стр.133] [стр.134] [стр.135] [стр.136] [стр.137] [стр.138] [стр.139] [стр.140] [стр.141] [стр.142] [стр.143] [стр.144] [стр.145] [стр.146] [стр.147] [стр.148] [стр.149] [стр.150] [стр.151] [стр.152] [стр.153] [стр.154] [стр.155] [стр.156] [стр.157] [стр.158] [стр.159] [стр.160] [стр.161] [стр.162] [стр.163] [стр.164] [стр.165] [стр.166] [стр.167] [стр.168] [стр.169] [стр.170] [стр.171] [стр.172] [стр.173] [стр.174] [стр.175] [стр.176] [стр.177] [стр.178] [стр.179] [стр.180] [стр.181] [стр.182] [стр.183] [стр.184] [стр.185] [стр.186] [стр.187] [стр.188] [стр.189] [стр.190] [стр.191] [стр.192] [стр.193] [стр.194] [стр.195] [стр.196]