На главную | Содержание | Назад | Вперёд
Наши друзья

 

 

Структура полезной нагрузки на платформе PA-RISC

Платформа HP/UX РА-RISC тоже основана на RISC-архитектуре. Размер использующихся команд составляет 32 бит. Этот процессор может работать как с прямым, так и обратным порядком байтов. Используются 32 общих регистра. Более подробную информацию наши читатели смогут получить из руководства Assembler Reference Manual, доступного по адресу http: //docs . hp., com.
Чтобы узнать, как язык ассемблера интерпретирует код на языке С на платформе HP/UX, воспользуйтесь следующей командой
ее -S
которая позволяет получить неисполняемый код на ассемблере (с расширением файла . s). С помощью программы ее файл с расширением . s может быть скомпилирован в исполняемый файл. Например, если у нас есть следующая программа на языке С
#include <stdio.h>
int main () {
printf("hello world\r\n") ; exit(l);
}
то с помощью команды cc -S создается файл test. s.
.LEVEL 1.1
.SPACE $TEXT$,SCRT=8
..SQBSPA $DO^$,Qn^^0^^^IG^=4„ACCESS=0x2c,CODE_ONLY,SCRT=24
main
. PROC
_(CALLINFC CALLER,FRAME-16,SAVE_RP
.ENTRY
STW %r2,-20((%r330))) /offset 0x0
LDC 64 (%r30),%r30 /offset 0x4
ADDIL LR"M$2-$global$,%r27,%rl /offset 0x8
LDC RR'M$2-$global${%rl),%r26 /offset Cxc
LDIL L'printf,%r31 /offset 0x10
..CALL AR(SW0=SR,RTNWAL=SR /in=2 6;out=2 8;
BE,L R'printf(%sr4,%r31),%r31 /offset 0x14
CCPY %r31,%r2 /offset 0x18
LDI I,%r26 /offset Cxlc
LDIL L'exit,%r31 /offset 0x20

ARGWO=GR, RTNVAL=GR R'exit (%sr4,%r31),%r31 %r31,%r2 -84 (%r30),%r2 %rO(%r2)
;in=26 ;offset
0x28
0x2c
0x30
out=2 8; 0x24
M$2
.CALL BE, L
COPY %r31,%r2 ,-offset LDW -84(%r30),%r2 ;offset
BV %r0(%r2) ,-offset
.EXIT
LDO -64 (%r30),%r30 /offset 0x34
.PROCEND ;out=28/ .SPACE $TEXT$ .SUBSPA $CODE$ .SPACE $PRIVATE$,SORT=16
.SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=0xlf, SORT=16
.ALIGN 8
.STRINGZ "hello world\r\n"
.IMPORT $global$,DATA .SPACE $TEXT$ .SUBSPA SCODES
.EXPORT main,ENTRY,PRIV_LEV=3,RTNVAL=GR .IMPORT printf,CODE .IMPORT exit,CODE . END
306
Глава 7
.CALL BE, L COPY LDW BV
.EXIT LDC
ARGWC=GR,RTNVAL=GR R'exit(%sr4,%r31),%r31
%r31,%r2
-84(%r30),%r2
%rC(%r2)
/offset /offset /offset
-64(%r30),%r30
;out = 2 8;
;in=2 6;out = 2 8;
/offset 0x24
0x28 0x2 c 0x3 0
0x3 4
M$2
/offset
.PRCCEND -SPACE $TEXT$ -SUBSPA $CCDE$ -SPACE $PRIVATE$,SCRT=16
-SUBSPA $DATA$,QUAD=l,ALIGN=8,ACCESS = 0xlf,SCRT=16
-ALIGN 8
.STRINGZ "hello world\r\n"
-IMPCRT $global$,DATA -SPACE $TEXT$ -SUBSPA $CCDE$
-EXPCRT main,ENTRY,PRIV_LEV=3,RTNVAL = GR -IMPCRT printf,CCDE .IMPCRT exit,CCDE -END
Теперь с помощью следующей команды мы можем скомпилировать файл test. s.
ее test. s
В результате мы получаем исполняемый двоичный файл а . out. Этот пример демонстрирует процесс программирования на ассемблере для платформы PA-RISC.
Пожалуйста, обратите особое внимание на следующие важные аспекты. void :.. END указывает на последнюю команду в файле на машинном языке.
. CALL определяет способ передачи параметров в последующий вызов функции. . PROC и . PROCEND указывают на начало и конец процедуры. Каждая процедура должна содержать .CALLINFOH . ENTER/ . LEAVE. . ENTER и . LEAVE обозначают точки пролога и эпилога процедуры.
Использование стека на компьютерах PA-RISC
В чипах на основе платформы PA-RISC не используется механизм call /ret. Однако используются стековые фреймы для хранения адресов возврата. Давайте
восп о7гьзуем|сзго11рогстой«;^(<8гр£1мп(вой,ь(что(бы1апр одемонстриррватьАкаклв архитектуре'
pAaRЙ&тсущй^йвляе'тся1 улрайлейи£"Иереходами и адресами возврата.
void func () { }
void func2() {
Void mairfumc2( )() ;

Это действительно очень просто. Нашей целью является демонстрация простейшей программы, в которой осуществляется операция ветвления (условного перехода).
Выполнение функции main () начинается приблизительно таким образом: сначала команда stw (store word) используется для сохранения в указателе значения адреса возврата функции (гр) в стеке со смещением -14 (-14 (srO, sp) ). Наш указатель стека установлен по адресу 0х7В03А2Е0. Смещение отнимается от адреса указателя стека, т.е. 0х7В03А2Е0 - 14 = 0х7В03А2СС. Текущее значение RP сохраняется по адресу памяти 0х7В03А2СС. Как видим, адрес возврата сохранен в стеке.
0х31Ь4 <main>: stw rp,-14(srC,sp)
Затем команда ldo (load offset) задает смещение 40 относительно текущей позиции указателя стека. Новым значением адреса указателя стека будет 0х7В0 ЗА2Е0 + 40 = 0х7В03А320.
0х31Ь8 <main+4>: ldo 40(sp),sp
Следующей командой является ldil (load immediate left), которая загружает 0x3000 в общий регистр г31. После этого выполняются команды be,l (branch external и link). При операции перехода используется значение из регистра г31 и добавляется смещение 17с (17с (sr4, г31) ), т.е. выполняется следующее вычисление 0x3000 + 17С = 0х317С. Теперь указатель на адрес возврата функции к нашей текущей позиции хранится в регистре r31 (%sr0, %r31).
0x31bc <main+8>: ldil 3000,r31
0х31с0 <main+12>: be,l 17c(sr4,r31),%sr0,%r31
Не забывайте о команде, выполняющейся в результате отложенной передачи управления. Команда ldo выполняется до операции ветвления. Она копирует значение из г31 в гр. Кроме того, помните, что в г31 хранится наш адрес возврата. Мы перемещаем его в указатель возврата RP. Кроме того, мы выполняем переход к функции func2 ().
0x31c4 <main+16>: ldo 0(r31),rp
Далее выполняется функция fun с 2 (). Выполнение начинается с сохранения текущего значения RP в стеке со смещением -14.
0x317c <func2>: stw rp,-14(srC,sp)
Затем добавляем 4 0 к значению нашего указателя стека.
0x3180 <func2+4>: ldo 40(sp),sp
Загружаем 0x3000 в регистр г31 для подготовки к следующему переходу, после чего вызываем команды be и 1 со смещением 174. Адрес возврата функции сохраняется в г 31, и мы переходим по адресу 0x3174.
0x3184 <func2+8>: ldil 3000,r31
0x3188 <func2+12>: be,l 174(sr4,r31),%sr0,%r31
До выполнения операции ветвления наша команда отложенной передачи управления перемещает адрес возврата функции из г 31 в гр.
0x318c <func2 + 16>: ldo 0(r31),rp
Теперь мы находимся в функции func () в конце строки. Поскольку выполнены все действия, происходит возврат из функции func (). Такую функцию часто называют листовой функцией (leaf function), поскольку она не вызывает никаких других функций. Таким образом, для этой функции не требуется сохранять копию значения гр. Возврат из функции осуществляется с помощью команды bv (branch vectored), чтобы перейти по адресу, сохраненному в гр. В качестве команды, выполняющейся при отложенной передаче управления, задана команда пор.
0x3174 <func>: bv rC(rp) 0x3178 <func+4>: пор
Теперь мы вернулись в func2 (). Следующая команда записывает сохраненный адрес возврата из функции со смещением -54 в гр.
0x3190 <func2 + 20>: ldw -54 (srC,sp),rp
Затем мы осуществляем возврат из функции с помощью команды bv.
0x3194 <func2+24>: bv r0(rp)
Вспомним о нашей отложенной передаче управления. До завершения команды bv мы исправляем значение указателя стека на его оригинальное значение до вызова функции func2 ().
0x3198 <func2+28>: ldo -40(sp),sp
Возвращаемся в функцию main () и повторяем те же действия. Загружаем старое значение указателя возврата из стека. Далее исправляем значение указателя стека и возвращаемся с помощью команды bv.
0x31c8 <main+20>: ldw -54 (srC,sp),rp
0x31cc <main+24>: bv rC(rp)
0x31d0 <main+28>: ldo -40(sp),sp

 

На главную | Содержание | Назад | Вперёд
 
Яндекс.Метрика