Реклама:

А теперь рассмотрим ту же программу на ассемблере UltraSPARC III (листинг 5.8). Поскольку программа для UltraSPARC III совершенно нечитабельна даже после длительной практики, мы решили определить несколько символов, чтобы прояснить дело. Чтобы такая программа работала, ее перед ассемблированием нужно пропустить через программу под названием срр (препроцессор С). Здесь мы используем строчные буквы, поскольку ассемблер UltraSPARC III этого требует (это на тот случай, если читатели захотят набрать эту программу и запустить).

Листинг 5.8. Решение задачи "Ханойская башня" для UltraSPARC III

Idefine N %i 0 /* N - это входной параметр 0 */

Idefine I %М /* I - это входной параметр 1 */

Idefine J %i2 /* J - это входной параметр 2 */

Idefine К Я10 /* К - это локальная переменная 0 */

Idefine ParamO %oQ /* ParamO - это выходной параметр 0 */

Idefine Paraml %ol /* Paraml - это выходной параметр 1 */

Idefine Param2 %о2 /* Param2 - это выходной параметр 2 */

Idefine Scratch Ш /* в срр комментарии записываются как в С*/

.proc 04 .global towers towers: save ^sp,-112. %sp

cmp N, 1 ! if(n- 1)

bne Else ! if (n != 1) goto Else

sethi %hi(format), ParamO ! printf("Переместить диск с %6 на %й\п", ! i, j)

or ParamO, Ulo(format), ParamO ! ParamO - адрес форматирующей строки

mov I, Paraml ! Paraml = i

call printf ! вызов printf ДО установки параметра 2 (j)

mov J, Param2 ! пустая операция для установки параметра 2

b Done ! завершение

nop ! вставляет пустую операцию

Else: mov 6, К ! начало вычисления к = 6 -i-j

sub K.J.К ! k=6-j

sub K.I.K ! k=6-i-j

add N, -1, Scratch ! начало процедуры towers(n-l, i, k)

mov Scratch, ParamO ! Scratch = n-1

mov I, Paraml ! параметр 1 = i

call towers ! вызов towers ДО установки параметра 2 (k)

mov К, Param2 ! пустая операция после вызова

! процедуры для установки параметра 2

mov 1, ParamO ! начало процедуры towersd, i, j)

mov I, Paraml ! параметр 1 = i

call towers ! вызов towers ДО установки параметра 2 (j)

mov J, Param2 ! параметр 2 = j

mov Scratch, ParamO ! начало процедуры towers(n-1, k, j)

mov K, Paraml ! параметр 1 = k

call towers ! вызов towers ДО установки параметра 2 (j)

mov J. Param2 ! параметр 2 = j

Done: ret ! выход из процедуры

restore ! вставка пустой команды после ret

! для восстановления окон format: .asciz "Переместить диск с %6 на %6\п"

По алгоритму версия UltraSPARC III идентична версии Pentium 4. В обоих случаях сначала проверяется п, и, если n > 1, совершается переход к else. Основные сложности версии UltraSPARC III связаны с некоторыми свойствами архитектуры команд.

Сначала код UltraSPARC III должен передать адрес форматирующей строки в printf, но машина не может просто переместить адрес в регистр, который содержит выходной параметр, поскольку нельзя поместить 32-разрядную константу в регистр одной командой. Для этого требуется выполнить две команды: sethi и ог.

После вызова не нужно делать подстройку стека, поскольку регистровое окно корректируется командой restore в конце процедуры. Возможность помещать выходные параметры в регистры, а не обращаться к памяти, дает значительный выигрыш в производительности.

А теперь рассмотрим команду пор, которая следует за Done. Это пустая операция, которая всегда будет выполняться, даже если она следует за командой условного перехода. Сложность состоит в том, что процессор UltraSPARC III очень конвейеризирован, и к тому моменту, когда аппаратно обнаруживается команда перехода, следующая команда уже практически заканчивает обрабатываться. Добро пожаловать в удивительный мир RISC-программирования!

Эта особенность распространяется и на вызовы процедур. Рассмотрим первый вызов процедуры towers в части el se. Процедура помещает п - 1 в %о0, ai - в %ol, но совершает вызов процедуры towers до того, как поместит последний параметр в нужное место. На компьютере Pentium 4 вы сначала передаете параметры, а затем вызываете процедуру. А здесь вы сначала передаете часть параметров, затем вызываете процедуру, и только после этого передаете последний параметр. К тому моменту, когда машина осознает, что она имеет дело с командой cal 1, следующую команду все равно приходится выполнять (из-за конвейеризации). А почему бы в этом случае не использовать пустую операцию, чтобы передать последний параметр? Даже если этот параметр потребуется самой первой команде вызванной процедуры, он уже будет на своем месте.

Наконец, рассмотрим часть команды Done. Здесь после команды ret тоже вставляется пустая операция. Эта пустая операция используется для команды restore, которая увеличивает на 1 значение CWP, чтобы вернуть регистровое окно в прежнее состояние.

Архитектура IA-64 и процессор Itanium 2

Неизбежно, и очень скоро, наступит момент, когда создать на основе архитектуры команд IA-32 и линейки процессоров Pentium 4 что-то более совершенное, чем существующие модели, будет уже невозможно. Пока что новые модели совершенствуются только благодаря новым технологиям производства, которые позволяют уменьшать размеры транзисторов, а значит, повышать тактовые частоты. В то же время, повышать скорость работы становится все труднее, и виной тому - ограничения, свойственные архитектуре команд IA-32.

Единственное эффективное решение проблемы - при разработке новых процессоров перейти от IA-32 к новой архитектуре команд. Именно такие планы строит компания Intel. Более того, предполагается запустить две новых линейки. Первая из них, называемая ЕМТ-64, представляет собой расширенную версию Pentium 4 с 64-разрядными регистрами и 64-разрядным же адресным пространством. В этой архитектуре решается проблема адресного пространства, но сложности реализации, свойственные Pentium 4, сохраняются. Ее можно назвать расширенным вариантом архитектуры Pentium.

Еще одна архитектура, которую совместно разрабатывают компании Intel и Hewlett Packard, называется IA-64. Это уже полноценная 64-разрядная машина. Более того - она во многих отношениях разительно отличается от Pentium 4. Первоначально IA-64 предполагается вывести на рынок профессиональных серверных систем, но вполне возможно, что впоследствии эта архитектура укрепится и в сегменте настольных компьютеров. В любом случае архитектура IA-64, впервые реализованная в линейке процессоров Itanium, настолько отличается от всего, что мы рассматривали ранее, что просто необходимо познакомиться с ней поближе. Итак, оставшаяся часть раздела посвящена архитектуре IA-64 как таковой и ее реализации в процессорах серии Itanium 2.

Решение задачи "Ханойская башня" на ассемблере Pentium 4 || Оглавление || Проблема Pentium 4