:: Статистика ::

 
Індекс цитування

 

 

 

 

 

Непрямо-регістровий режим із зсувом

Адреса операнда утворюється шляхом складання регістра і адресного поля команди. Цей режим найбільш багатий можливостями і, залежно від стилю використання, має багато інших назв, наприклад базова адресація або індексна адресація. Адресне поле необов'язково містить повноцінну адресу і може бути укороченим.
Команди id/st процесора SPARC, використовувані в прикладі 2.2, реалізують непрямо-регістрову адресацію з 13-розрядним зсувом.
Можливі варіанти використання цього режиму адресації багаточисельні. Наприклад, якщо зсув є абсолютною адресою початку масиву, а в регістрі зберігається індекс, цей режим може використовуватися для індексації масиву. В цьому випадку зсув має бути повноцінною адресою.
3 іншому випадку, в регістрі може зберігатися покажчик на структуру Даних, а зсув може означати зсув конкретного поля відносно початки структури. Ще один варіант -- регістр зберігає покажчик на стековий кадр або блок параметрів процедури, а зсув -адрес локальної змінної в цьому кадрі або певного параметра.
У цих випадках можна використовувати (і зазвичай використовується) укорочений зсув.

Стековий кадр

Стековий кадр є стандартним способом виділення пам'яті під локальні змінні в алголоподобных процедурних мовах (З, C++, Pascal) і інших мовах, що допускають рекурсивні виклики.
Семантика рекурсивного виклику в алголоподобных мовах вимагає, аби кожна з рекурсивно викликаних процедур мала власну копію локальних змінних. У SPARC це досягається зрушенням регістрового вікна по регістровому файлу (мал. 2.9), але більшість інших процесорів такої розкоші позбавлені і вимушені виділяти пам'ять під локальні змінні в стеку, що розміщується в ОЗУ.

Мал. 2.9. Регістровий стек процесора SPARC

Для цього викликана процедура зменшує (якщо стек зростає вниз) покажчик стека на кількість байтів, достатню, аби розмістити змінні. Адресація цих змінних біля деяких процесорів (наприклад, біля PDP-11) відбувається відносно покажчика стека, а у більшості — наприклад, біля Мс680хо і VAX, з великою кількістю регістрів або біля х86, покажчик стека якого не можна використовувати для адресації із зсувом — для цієї мети виділяється окремий регістр (мал. 2.10, приклад 2.4).

Приклад 2.4. Формування, використання і знищення стекового кадру. Код на мові З і результат його обробки GNU З 2.7.2.1 (коментарі автора)

#include <stdio.h>
# include <strings.h>

/* Фрагмент примітивної реалізації сервера SMTP (RFC822) */
int parse_line(FILE * socket)
{
/* Згідно RFC822, команда має довжину не більше 4 байт, а весь рядок — не більше 255 байт V char cmd[5], args [255]; fscanf (socket, "%s %s\n", cmd, args);
if (stricmpfcmd, "HELO")==0) {
fprintf (socket, "200 Hello %s, glad to meet you\n", args);
return 200;
)
/* etc */
fprintf (socket, "500 Unknown command %s\n", cmd);
return 500;
.file "sample" gcc2_compiled. : _ gnu_compiled_c : .text LCO:
.ascii "%s %s\12\0" LCI:
.ascii "HELCAO" LC2:
.ascii "200 Hello %s, glad to meet you\12\0" LC3:
.ascii "500 Unknown command %s\12\0"
.align 2, 0x90 .globl _parse_line _parse_line:
; x86 має для цієї мети спеціальну команду enter, але вона може ; формувати кадри розміром не більше 255 байт. В даному випадку кадр ; має більший розмір, і його необхідно формувати уручну.
pushl %ebp ; Зберігаємо покажчик кадру
; підпрограми, що викликала нас.
movl %esp, %ebp ; Формуємо покажчик нашого кадру
subl $264,%esp ; І сам кадр. ; Кінець прологу функції
leal -264 (%ebp), %еах ; Поміщаємо в стек покажчик на args • pushl %eax
leal -8 (%ebp), %еах ; ... на cmd
pushl %eax
pushl $LCO ; на строкову константу
; Наші власні параметри теж адресуються відносно кадру. movl 8(%ebp),%eax ; Параметр socket ми теж проштовхуємо pushl %eax ; у стек
call fscanf ; Виклик (параметри в стеку) addl $16,%esp ; очищаємо стек
; у мові Із змінна кількість параметрів, тому вичищати їх
; стека повинна зухвала процедура. Та, що викликається просто не знає
; СКІЛЬКИ ЇХ бЫЛО.
pushl $LC1
leal -8(%ebp),%eax
pushl %eax
call _stricmp
addl $8,%esp
movl %eax,%eax ; вимкнена оптимізація у дії :)
; Адже недалекі часи, коли компілятори лише таке і уміли ; генерувати.
testl %eax,%еах
jne L14
leal -264(%ebp),%еах
pushl %eax
pushl $LC2
movl 8(%ebp),%eax
pushl %eax
call _fprintf
addl $12,%esp
; Звернете увагу, що компілятор не став генерувати другий епілог ; функції на другому операторові return.
movl $200,%eax
jmp L13
» Вирівнювання потенційних точок переходу на кордон слова корисно: » процесор не витрачатиме додатковий цикл шини на читання » невирівняної команди. Для вирівнювання використовується команда NOP ; (код операції 0x90).
align 2,0x90 L14:
leal -8(%ebp),%еах
Pushl %eax
Pushl $LC3
movl 8(%ebp),%eax pushl %eax
call _fprintf
addl ?12,%esp
movl $500,%eax
jmp L13
.align 2,0x90 L13:
; Команда leave здійснює дії, зворотні прологу функції: ; Вона еквівалентна командам: move %ebp, %esp; pop %ebp. ; Розмір кадру явним чином не вказується, тому обмежень ; на цей розмір в даному випадку немає.
leave
ret

Мал. 2.10. Стековий кадр

Примітка
Звернете увагу, що програма з прикладу 2.4 містить серйозну помилку. У коментарях сказано, що команда зобов'язана мати довжину не більше 4 байт, а весь рядок разом з аргументами не більше 255. Якщо програма-клієнт на іншому кінці сокета (мережевого з'єднання) відповідає RFC822 [RFC822], так воно і буде. Але якщо програма вимогам цього документа не відповідає, нас чекає біда: нам можуть запропонувати довшу команду і довший рядок. Наслідки, до яких це може привести, будуть детальніше знатися на главі 12.

Але повернемося до стекових кадрів.

Стекові кадри в системі команд SPARC
Мікропроцесори SPARC також не можуть обійтися без стекового кадру. По-перше, не завжди локальні змінні процедури поміщаються у восьми 32-розрядних локальних регістрах. Саме такий процедура приведена в прикладі 2.4. По-друге, нерідкі ситуації, коли як параметри треба передати за значенням структури, для яких 6 регістри-параметрів теж не хватит. По-третє, глибина регістрового файлу обмежена і при роботі рекурсивних або просто глибоко вкладених процедур може вичерпатися. По-четверте, в багатозадачній системі регістровий файл може одночасно використовуватися декількома завданнями. Всі ці проблеми вирішуються за допомогою створення стекового кадру [www.sparc.com v9].
Для цієї мети використовуються регістри Isp (о6) і %fp (i6). Команда save %sp, -96 %sp робить наступне: вона складає перші два операнди, зрушує стековий кадр і поміщає результат складання в третій операнд. Завдяки такому порядку виконання окремих операцій, старий %sp стає %fp, а результат складання поміщається вже в новий %sp.
Найважливішу роль стекові кадри грають при обробці переповнювань регістрового файлу. Регістровий файл SPARC є кільцевим буфером, доступність окремих ділянок якого описується привілейованими регістрами CANSAVE і CANRESTORE. Вікна, що знаходяться між значеннями цих двох регістрів, доступні поточній програмі (мал. 2.11). На малюнку показаний стан регістрового файлу, в якому поточний процес може відновити один стековий кадр (CANRESTORE=1) і зберегти три (CANSAVE=3). Регістр OTHERWIN вказує кількість регістрових вікон, зайнятих іншим процесом. Регістрове вікно w4 на малюнку (позначене як перекриття) зайняте лише частково. Поточне вікно, частково зайняте вікно і ділянки регістрового файлу, описані перерахованими регістрами, в сумі повинні складати весь регістровий файл, так аби дотримувалося відношення CANSAVE + CANRESTORE + OTHERWIN = NWINDOWS - 2, Де NWINDOWS- кількість вікон (на малюнку регістровий файл має 8 вікон, тобто 128 регістрів).

Мал. 2.11. Регістровий файл SPARC у вигляді кільцевого буфера. Регістри CANSAVE і CANRESTORE (цит. по [www.sparc.com v9])

Коли ж програма намагається зрушити своє вікно за описані кордони (у ситуації, змальованій на рис 2.11 це може статися після викликів чотирьох вкладених процедур або після повернення з двох процедур, — поточною і відповідною окну w7), генеруються виняткові стани заповнення вікна (window fill) і скидання вікна (window spill). При цьому викликається системна процедура, яка звільняє вікна з інтервалу OTHERWIN, скидаючи їх вміст в стекові кадри відповідних процедур і при заповненні відновлює вміст вікна, що належить нам, з відповідного кадру.
У багатозадачній системі заповнення і скидання вікна може статися у будь-який момент, тому призначена для користувача програма завжди повинна мати по стековому кадру на кожне з використовуваних нею регістрових вікон, а покажчик на цей кадр повинен завжди лежати в %sp відповідного вікна. При цьому дуже поважно, аби створення стекового кадру і зрушення регістрового вікна вироблялися однією командою.

 

рекламодавці:

/ ml lfppюн Всегда свежие цветы, стильные и композиции доставка цветов севастополь.

::  Меню ::

ГОЛОВНА

Введення

Представлення даних в обчислювальних системах 

Машинні мови

Завантаження програм 

Управління оперативною пам'яттю

Сегментна і сторінкова віртуальна пам'ять

Комп'ютер і зовнішні події

Паралелізм з точки зору програміста 

Реалізація багатозадачності на однопроцесорних комп'ютерах 

Зовнішні пристрої

Драйвери зовнішніх пристроїв 

Файлові системи 

Додаток. Огляд архітектури сучасних ОС

 


:: Навігація ::

Головна

Додати у вишукане  

 

 

 


Copyright © Asentli, 2008