Ассемблер для Power-архитектуры, Часть 3: Программирование с использованием процессора ветвлений PowerPC

Более внимательный взгляд на команды и регистры ветвления

В двух предыдущих статьях обсуждалось то, как работают программы, использующие 64-битный набор команд PowerPC® на процессоре POWER5, как команды PowerPC работают с памятью, и как создать позиционно-независимый код. Эта статья рассматривает очень мощные условные команды и команды ветвления, доступные в наборе команд PowerPC.

Джонатан Бартлетт, технический директор, New Media Worx

Джонатан Бартлет (Jonathan Bartlett) является автором книги "Программирование с нуля" - введения в программирование на языке ассемблера для Linux. Он является ведущим разработчиком в New Media Worx и занимается Web-приложениями (видео, киосками), а также настольными приложениями для клиентов. Вы можете связаться с ним по адресу johnnyb@eskimo.com.



24.04.2007

Регистры ветвления

Ветвления в PowerPC используют три регистра специального назначения: регистр условий (condition register), регистр счетчик (count register) и регистр связи (link register).

Регистр условий

Регистр условий по существу состоит из семи полей. Поле это область из четырех битов, используемая для хранения информации о результатах выполнения команды. Два поля - специального назначения и будут обсуждены коротко, а остальные поля доступны для общего использования. Поля называются cr0 ... cr7.

Первое поле, cr0 используется для результатов команд, производящих вычисления с фиксированной точкой, которые не используют непосредственные операнды (за некоторыми исключениями). Результат вычисления сравнивается с нулем, и устанавливаются соответствующие биты (отрицательный, ноль или положительный). Чтобы указать в вычислительной команде, что вы хотите, чтобы были установлены биты в cr0, вы просто добавляете точку (.) в конец команды. Например, add 4, 5, 6 складывает регистр 5 с регистром 6 и сохраняет результат в регистре 4 без установки каких бы то ни было битов в cr0. А add. 4, 5, 6 делает то же самое, но устанавливает биты в cr0 на основании вычисленного значения. cr0 также является стандартным полем при использовании команд сравнения.

Второе поле (называемое cr1) используется для команд, оперирующих с плавающей точкой, у которых в конце команды стоит точка. Вычисления с плавающей точкой выходят за рамки этой статьи.

Каждое поле имеет четыре бита. Назначение этих битов зависит от выполняемой команды. Ниже -- их возможные значения (значения битов для операций с плавающей точкой перечислены, но не описаны):

Биты поля регистра условий
БитОбозначениесравнение с фиксированной точкойВычисления с фиксированной точкойСравнение с плавающей точкойВычисления с плавающей точкой
0ltМеньше чемОтрицательноМеньше чемException summary
1gtБольше чемПоложительноБольше чемEnabled exception summary
2eqРавноНольРавноInvalid operation exception summary
3soSummary overflowSummary overflowНеупорядоченныйOverflow exception

Ниже вы увидите, как получить доступ к этим полям как явно, так и неявно.

Регистр условий может быть загружен в или из одного из регистров общего назначения при помощи команд mtcr, mtcrf и mfcr. Команда mtcr перемещает указанный регистр общего назначения в регистр условий. mfcr - перемещает регистр условий в регистр общего назначения. mtcrf - загружает в регистр условий биты из регистра общего назначения, но только те биты, что указанны в 8 битовой маске, которая является первым операндом.

Ниже несколько примеров:

Листинг 1. Примеры перемещений регистра условий
#Копировать регистр 4 в регистр условий
mtcr 4

#Копировать регистр условий в регистр 28
mfcr 28

#Копировать поля 0, 1, 2 и 7 из регистра 18 в регистр условий
mtcrf 0b11100001, 18

Регистр счетчик и регистр связи

Регистр связи (обозначаемый LR) -- это специальный регистр, который содержит адрес возврата из операции ветвления. Всем командам ветвления может быть указано устанавливать регистр связи, и, если ветвление происходит, регистр связи устанавливается равным адресу команды, следующей непосредственно за оператором ветвления. Команды ветвления устанавливают регистр связи, если к ним добавить букву l в конце команды. Например, b -- это безусловный оператор перехода, а bl -- безусловный оператор перехода, который устанавливает регистр связи.

Регистр счетчик (обозначаемый CTR) -- это специальный регистр, предназначенный для хранения счетчиков циклов. Специальные команды ветвления могут уменьшать регистр-счетчик и/или осуществлять переход в зависимости от того, достиг CTR нуля или нет.

Оба регистра могут быть использованы как адрес перехода. bctr переходит по адресу, указанному в регистре-счетчике, а blr переходит по адресу, указанному в регистре связи.

Регистр связи и регистр-счетчик также могут быть загружены или скопированы из регистров общего назначения. Для регистра связи mtlr перемещает значение указанного регистра в регистр связи, а mflr перемещает значение из регистра связи в регистр общего назначения. mtctr и mfctr делают то же самое для регистра счетчика.


Безусловные переходы

Безусловные переходы в наборе команд PowerPC используют формат команд I-Form:

Формат команд I-Form

Биты 0-5

Код операции

Биты 6-29

Абсолютный или относительный адрес перехода

Бит 30

Бит абсолютного адреса - если установлен, адрес интерпретируется как абсолютный, иначе как относительный

Бит 31

Бит связи - если этот бит установлен, команда загружает в регистр связи адрес следующей команды

Как упоминалось раньше, добавление буквы l к команде перехода устанавливает бит связи таким образом, что "адрес возврата" (команда после команды перехода) сохраняется в регистре связи. Если вы добавите букву a в конец команды (она идет после l, если l присутствует), то указанный адрес будет абсолютным (это не часто используется в пользовательском коде, поскольку очень сильно ограничивает диапазон переходов).

Листинг 2 демонстрирует безусловные переходы (назовите файл branch_example.s):

Листинг 2. Примеры безусловных переходов
### ОПИСАНИЕ ТОЧКИ ВХОДА ###
.section .opd, "aw"
.align 3
.globl _start
_start:
        .quad ._start, .TOC.@tocbase, 0

### КОД ПРОГРАММЫ ###
.text
#перейти к метке t2
._start:
        b t2

t1:
#перейти к метке t3, устанавливая регистр связи
        bl t3
#Эта команда, к которой мы возвращаемся
        b t4

t2:
#переход к метке t1 как к абсолютному адресу
        ba t1

t3:
#переход к адресу указанному в регистре связи
#(т.е. адрес возврата)
        blr

t4:
        li 0, 1
        li 3, 0
        sc

Ассемблируйте, скомпонуйте и запустите программу следующим образом:

as -a64 branch_example.s -o branch_example.o
ld -melf64ppc branch_example.o -o branch_example
./branch_example

Заметьте, что метки как для b, так и для ba указываются в ассемблере одинаково, несмотря на то, что они кодируются в команде по-разному. Ассемблер и компоновщик позаботятся о преобразовании адреса метки в относительный или абсолютный адрес.


Условные переходы

Сравнение регистров

Команда cmp используется для сравнения регистров с другими регистрами или с непосредственными операндами и устанавливает соответствующие биты состояния в регистре условий. Команды сравнения с фиксированной точкой используют по умолчанию cr0, чтобы сохранить результат, но поле также может быть указано как дополнительный первый операнд. Команды сравнения приведены в листинге 3:

Листинг 3. Примеры команд сравнения
#Сравнить регистр 3 и регистр 4 как двойные слова (64 бита)
cmpd 3, 4

#Сравнить регистр 5 и регистр 10 как беззнаковые двойные слова (64 бита)
cmpld 5, 10

#Сравнить регистр 6 и число 12 как слово (32 биита)
cmpwi 6, 12

#Сравнить регистр 30 и регистр 31 как двойное слово (64 бита)
# и сохранить результат в cr4
cmpd cr4, 30, 31

Как можно видеть, d определяет, что операнды являются двойными словами, тогда как w определяет операнды как слова. i указывает на то, что последний операнд -- есть непосредственная величина, а не регистр, и l сообщает процессору, что надо выполнить сравнение без знаков (называемое также логическим сравнением), вместо сравнения со знаком.

Каждая из этого набора команд устанавливает соответствующие биты в регистре условий (как было сказано раньше в этой статье). Регистр условий может быть потом использован командой условного перехода.

Основы условных переходов

Условные переходы являются гораздо более гибкими, чем безусловные переходы, но это достигается ценой доступного для перехода расстояния. Условные переходы используют формат команд B-Form:

Формат команд B-Form

Биты 0-5

Код операции

Биты 6-10

Определяют опции, используемые по отношению к тому, как тестируется бит, как регистр счетчик будет использоваться, а также любые подсказки, прогнозирующие ветвление (называется полем BO)

Биты 11-15

Определяют на бит в регистре условий, который надо проверять (называется полем BI)

Биты 16-29

Абсолютный или относительный адрес

Бит 30

Режим адресации -- когда установлен равным 0, указывает, что адрес рассматривается как относительный, а когда 1, как абсолютный адрес

Бит 31

Бит связи -- когда установлен равным 1, регистр связи устанавливается равным адресу следующему за текущей командой, когда установлен равным 0, регистр связи не устанавливается

Как вы видите, целых 10 бит используются для указания способа ветвления и условия, что ограничивает размер адреса всего 14 битами (диапазон всего 16К). Это можно использовать для маленьких скачков в пределах функции и ни для чего больше. Чтобы условно вызвать функцию извне этого 16 К диапазона, коду пришлось бы сделать условное ветвление к команде, содержащей безусловный переход к правильной ячейке.

Основные формы условных переходов выглядят следующим образом:

bc BO, BI, address
bcl BO, BI, address
bca BO, BI, address
bcla BO, BI, address

В основной форме BO и BI являются числами. К счастью, мы не должны запоминать все числа и что они значат. Расширенная символика набора команд PowerPC (описанная в первой статье) опять нас спасет, и мы сможем избежать необходимости запоминать все значения полей. Так же, как в безусловном переходе, присоединение l к имени команды устанавливает регистр связи, а присоединение a заставляет команду использовать абсолютную адресацию вместо относительной.

Для простого сравнения и перехода "если равно" основная форма (не используя расширенной символики) выглядит следующим образом:

Листинг 4. Основная форма условного перехода
#сравнить регистр 4 и 5
cmpd 4, 5
#перейти, если они равны
bc 12, 2 address

bc означает "branch conditionally"(условный переход). 12 (операнд BO) означает перейти, если данное поле в регистре условий установлено без подсказок, прогнозирующих ветвление, и 2 (операнд BI) представляет собой бит регистра условий для проверки (это бит равенства). Очень немногие люди, особенно начинающие, в состоянии запомнить все коды ветвлений и номера битов регистра условий, но это и не нужно. Расширенная символика делает код более понятным для чтения, написания и отладки.

Есть несколько разных путей для спецификации расширенной символики. Путь, на котором мы сконцентрируемся, комбинирует имена команд и операнд BO (указывающий на режим) команды. Простейшими из них являются bt и bf. bt означает переход, если данный бит из регистра условий установлен в значение истина (true), и bf означает переход, если данный бит из регистра условий установлен в значение ложь (false). Кроме того, бит регистра условий может быть указан с символикой. Если вы указываете 4*cr3+eq, это означает проверку бита 2 из cr3 (4* добавлено сюда, так как каждое поле шириной в 4 бита). Имеющаяся символика для каждого бита из полей битов была приведена ранее при описании регистра условий. Если вы указываете только на бит, без указания на поле, команда по умолчанию будет cr0.

Ниже несколько примеров:

Листинг 5. Простые условные переходы
#Перейти, если бит равенства в cr0 установлен
bt eq, where_i_want_to_go

#Перейти, если бит равенства в  cr1 не установлен
bf 4*cr1+eq, where_i_want_to_go

#Перейти, если отрицательный бит (обозначение "lt") в cr5 установлен
bt 4*cr5+lt, where_i_want_to_go

Другой набор расширенной символики комбинирует команды, операнд BO и бит условия (бит, но не поле). Здесь используется более или менее традиционная символика для различных типов обычных условных ветвлений. Например, bne my_destination (перейти к my_destination, если не равно) эквивалентно bf eq, my_destination (перейти к my_destination, если бит eq установлен в значение ложь). Чтобы использовать разные поля регистра условий с помощью этого набора символов, просто укажите поле в операнде перед адресом назначения, например, bne cr4, my_destination. Ниже приведена символика ветвлений, построенная по этому образцу: blt (меньше чем), ble (меньше чем или равно), beq (равно), bge (больше чем или равно), bgt (больше чем), bnl (не меньше чем), bne (не равно), bng (не больше чем), bso (summary overflow), bns (not summary overflow), bun (неупорядоченный – только для плавающей точки) и bnu (не неупорядоченный – только для плавающей точки).

Все символики и расширенные символики могут содержать присоединенные к ним l и/или a, чтобы устанавливать регистр связи или абсолютную адресацию, соответственно.

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

Дополнительные особенности регистра условий

Так как регистр условий имеет много полей, различные вычисления и сравнения могут использовать разные поля, и логические операции могут быть использованы для объединения условий. Все логические операции имеют следующую форму: cr<opname> target_bit, operand_bit_1, operand_bit_2. Например, чтобы сделать логическое and для eq бита поля cr2 и lt бита поля cr7 и сохранить их в eq бите поля cr0, вам надо написать: crand 4*cr0+eq, 4*cr2+eq, 4*cr7+lt.

Вы можете перемещать поля регистра условий, используя mcrf. Чтобы копировать cr4 в cr1, следует написать mcrf cr1, cr4.

Команды ветвления могут также давать подсказки процессору ветвлений для предсказания ветвлений. Для большинства команд ветвления присоединение + к команде сигнализирует процессору ветвлений, что это ветвление будет, вероятно, иметь место. Присоединение - к команде сигнализирует о том, что это ветвление, вероятно, не будет выполняться. Однако это обычно не нужно, так как процессор ветвлений в процессоре POWER5 в состоянии достаточно хорошо предсказывать ветвления.


Использование регистра счетчика

Регистр счетчик – это специальный регистр, используемый для счетчика циклов. Операнд BO (контролирующий режим) условного перехода может быть использован не только для указания, как проверять биты регистра условий, но и чтобы уменьшать и проверять регистр счетчик. Есть две операции, которые вы можете делать с регистром счетчиком:

  • уменьшить регистр счетчик и выполнить ветвление, если он равен нулю
  • уменьшить регистр счетчик и выполнить ветвление, если он не равен нулю

Эти операции с регистром счетчиком могут быть использованы как сами по себе, так и совместно с контролем регистра условий.

В расширенной символике семантика регистра счетчика указывается путем добавления или dz, или dnz сразу после b. Любые дополнительные условия или модификатор команды добавляются после этого. Так что, чтобы повторить цикл 100 раз, вы должны загрузить в регистр счетчик число 100 и использовать bdnz. Ниже показано, как будет выглядеть код:

Листинг 6. Пример цикла, контролируемого счетчиком
#Регистр счетчик должен быть загружен через регистр общего назначения
#Загрузить в регистр 31 число 100
li 31, 100
#Переместить его в регистр счетчик
mtctr 31

#Адрес начала цикла
loop_start:

###здесь находится тело цикла###

#Уменьшить регистр счетчик и перейти, если он стал не равен 0
bdnz loop_start

#Здесь идет код после цикла

Вы можете также объединить проверку счетчика с другими проверками. Например, цикл может нуждаться в условии раннего выхода. Следующий код демонстрирует условие раннего выхода, когда регистр 24 равен регистру 28.

Листинг 7. Пример ветвления комбинированного с регистром счетчиком
#Регистр счетчик должен быть загружен из регистра общего назначения
#Загрузить в регистр 31 число 100
li 31, 100
#Переместить его в регистр счетчик
mtctr 31

#Адрес начала цикла
loop_start:

###здесь находится тело цикла###

#Проверить на условие раннего выхода (регистр 24 равен регистру 28)
cmpd 24, 28

#Уменьшить регистр счетчик, и перейти, если не 0, и также проверить условие раннего выхода
bdnzf eq, loop_start

#Здесь идет код после цикла

Так что вместо того, чтобы добавлять дополнительные команды условного перехода, все, что вам нужно, -- это команда сравнения и условный переход, объединенный с переходом по счетчику цикла.


Объединяя все вместе

Теперь мы применим эту информацию на практике.

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

Листинг 8. Улучшенная версия программы нахождения максимального числа
###ДАННЫЕ ПРОГРАММЫ###
.data
.align 3

value_list:
   .quad 23, 50, 95, 96, 37, 85
value_list_end:

#Вычислить константу, содержащую размер списка
.equ value_list_size, value_list_end - value_list

###ОПИСАНИЕ ТОЧКИ ВХОДА###
.section .opd, "aw"
.global _start
.align 3
_start:
   .quad ._start, .TOC.@tocbase, 0


###КОД###
._start:   
   .equ DATA_SIZE, 8

   #ИСПОЛЬЗОВАНИЕ РЕГИСТРОВ
   #Регистр 3 -- текущий максимум
   #Регистр 4 -- список адресов
   #Регистр 5 -- текущий индекс
   #Регистр 6 -- текущее значение
   #Регистр 7 -- размер данных (отрицательный)

   #Загрузить адрес списка
   ld 4, value_list@got(2)
   #Регистр 7 содержит размер данных (отрицательный)
   li 7, -DATA_SIZE
   #Load the size of the list
   li 5, value_list_size
   #Установить  "Текущий максимум" равным  0
   li 3, 0
   
loop:
   #Уменьшить индекс до следующего значения, установить статус регистр (в cr0)
   add. 5, 5, 7

   #Загрузить значение (X-Form - сложить регистр 4 и регистр 5 для конечного адреса)
   ldx 6, 4, 5

   #Сравнить без знака текущую величину с текущим максимумом (использовать cr2)
   cmpld cr2, 6, 3

   #Если текущая величина больше, установить ее 
   #как текущий максимум (устанавливает регистр связи)
   btl 4*cr2+gt, set_new_maximum 

   #Выполнять цикл до тех пор, пока последнее уменьшение индекса не приведет к нулю
   bf eq, loop

   #ПОСЛЕ ЦИКЛА -- выход
   li 0, 1
   sc

set_new_maximum:
   mr 3, 6
   blr (возвратиться, используя регистр связи)

Ассемблируйте, скомпонуйте и выполните как ранее:

as -a64 max_enhanced.s -o max_enhanced.o
ld -melf64ppc max_enhanced.o -o max_enhanced
./max_enhanced

Цикл в этой программе примерно на 15% быстрее, чем цикл в программе первой статьи, так как (а) мы выкинули некоторые команды из основного цикла, путем использования статус-регистра для определения конца списка, когда мы уменьшаем регистр 5, и (б) программа использует разные поля регистра условий для сравнения (так что результат уменьшения может быть сохранен для последующих операций).

Заметьте, что использование регистра связи для вызова команды set_new_maximum не является абсолютно необходимым. Программа работала бы также хорошо, если вместо регистра связи явно указать адрес возврата. Тем не менее, это хороший пример использования регистра связи.


Короткое введение в простые функции

Двоичный интерфейс приложений (ABI) PowerPC достаточно сложен. Он будет детально обсужден в следующей статье. Однако для функций, которые сами не вызывают никаких функций и подчиняются нескольким простым правилам, PowerPC ABI обеспечивает очень простой механизм вызова функции.

Для того, чтобы подходить для упрощенного ABI, ваша функция должна удовлетворять следующим условиям:

  • Она не должна вызывать никаких других функций.
  • Она может изменять только регистры с 3 по 12.
  • Она может только изменять поля следующих регистров условий cr0, cr1, cr5, cr6 и cr7.
  • Она не должна изменять регистр связи, кроме случая, когда она восстанавливает его перед вызовом blr для возврата.

Когда функции вызываются, параметры посылаются в регистры, начиная с регистра 3 и вплоть до регистра 10, в зависимости от числа параметров. Когда функция возвращается, возвращаемое функцией значение должно быть сохранено в регистре 3.

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

Параметры, которые мы должны передавать, -- это указатель массива как первый параметр (регистр3) и размер массива как второй параметр (регистр 4). А максимальная величина будет помещена в регистр 3 в качестве возвращаемого функцией значения.

Итак, вот наша программа, переформулированная как функция (назовите файл max_function.s):

Листинг 9. Программа нахождения максимального числа как функция
###ОПИСАНИЕ ТОЧКИ ВХОДА###
#Функции также требуют описания точки входа
.section .opd, "aw"
.global find_maximum_value
.align 3
find_maximum_value:
   .quad .find_maximum_value, .TOC.@tocbase, 0

###КОД###
.text
.align 3

#размер элемента массива
.equ DATA_SIZE, 8

#начало функции
.find_maximum_value:
   #ИСПОЛЬЗОВАНИЕ РЕГИСТРОВ
   #Регистр 3 -- адрес списка
   #Регистр 4 -- размер списка 
   #Регистр 5 -- текущий индекс в байтах (начинается с размера списка в байтах) 
   #Регистр 6 -- текущее значение
   #Регистр 7 -- текущий максимум
   #Регистр 8 -- размер данных

   #Регистры 3 и 4 уже загружены -- это произошло при вызове функции
   li 8, -DATA_SIZE
   
   #Расширить количество элементов до размера массива
   #(сдвигаем до кратности 8 (на три бита))
   sldi 5, 4, 3

   #Установить текущий максимум равным 0
   li, 7, 0
loop:
   #Перейти к следующему значению; установить статус регистр  (в cr0)
   add. 5, 5, 8

   #Загрузить значение (X-Form - складывает регистр 3 и регистр 5 
   #для получения результирующего адреса)
   ldx 6, 3, 5

   #Сравнение без знака текущего значения с текущим максимумом (использовать cr7)
   cmpld cr7, 6, 7

   #Если текущее значение больше, установить максимум равным ему
   bt 4*cr7+gt, set_new_maximum
set_new_maximum_ret:
   
   #Повторять, пока последний индекс не уменьшится до нуля
   bf eq, loop

   #ПОСЛЕ ЦИКЛА
   #Переместить результат в значение для возврата
   mr 3, 7
   
   #вернуться
   blr

set_new_maximum:
   mr 7, 6
   b set_new_maximum_ret

Все это очень похоже на белее раннюю версию, за исключением нескольких основных моментов:

  • Начальные условия передаются через параметры, а не жестко закодированы.
  • Использование регистров в рамках функции модифицировано, чтобы согласовать его с размещением передаваемых параметров.
  • Ненужное использование регистра связи для set_new_maximum было устранено, чтобы сохранить содержимое регистра связи.

Тип данных на С, с которыми работает программа, -- это unsigned long long Это довольно громоздко для написания, так что будет лучше переименовать это следующим образом uint64. Тогда прототипом функции будет:

uint64 find_maximum_value(uint64[] value_list, uint64 num_values);

Ниже приведена короткая управляющая программа для тестирования нашей новой функции (сохраните ее как use_max.c):

Листинг 10. Простая программа на С, использующая функцию нахождения максимума
#include <stdio.h>

typedef unsigned long long uint64;

uint64 find_maximum_value(uint64[], uint64);

int main() {
    uint64 my_values[] = {2364, 666, 7983, 456923, 555, 34};
    uint64 max = find_maximum_value(my_values, 6);
    printf("The maximum value is: %llu\n", max);
    return 0;
}

Чтобы скомпилировать и запустить программу, просто вызовите:

gcc -m64 use_max.c max_function.s -o maximum
./maximum

Заметьте, что поскольку мы теперь фактически выполняем форматированное печатание вместо возвращения величины в командную оболочку, мы можем использовать полный 64-битный размер элементов массива.

Вызовы простых функций очень экономичны, когда речь идет о производительности. ABI вызовов упрощенных функций полностью стандартен и обеспечивает простой способ написания программ на смеси языков, которые требуют скорости ассемблера в основных циклах и выразительности и простоты использования языков высокого уровня для всего остального.


Заключение

Знание всех тонкостей процессора ветвлений помогает в написании более эффективного PowerPC кода. Использование различных полей регистра условий дает возможность программисту интересными способами сохранять и комбинировать условия. Использование регистра счетчика помогает создавать эффективные циклы. Простые функции дают возможность даже новичку написать полезные функции на ассемблере для использования их в программах на языках более высокого уровня.

В следующей статье я буду рассматривать PowerPC ABI для вызовов функций и все о стековых функциях на платформах PowerPC.

Ресурсы

Научиться

Получить продукты и технологии

  • С помощью trial-версии программ IBM, доступных для скачивания с developerWorks, сделайте вашу следующую разработку на Linux.

Обсудить

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Linux
ArticleID=211841
ArticleTitle=Ассемблер для Power-архитектуры, Часть 3: Программирование с использованием процессора ветвлений PowerPC
publish-date=04242007