Project

General

Profile

Обзор работы со стеком » History » Version 19

krufter_multiclet, 04/03/2013 11:54 AM

1 1 krufter_multiclet
h1. Обзор работы со стеком
2 1 krufter_multiclet
3 1 krufter_multiclet
Стек необходим прежде всего для взаимодействия Си компилятора и ассемблера: передача аргументов функций,
4 11 krufter_multiclet
передача параметров, сохранение значений для возврата в функцию, возврат в Си результатов и т.п.
5 1 krufter_multiclet
6 1 krufter_multiclet
Стек в мультиклеточном процессоре организован при помощи индексных регистров 38,39.
7 17 krufter_multiclet
Регистр 38 имеет имя BP (база стека), регистр 39 называется SP (вершина стека).
8 1 krufter_multiclet
9 1 krufter_multiclet
Стек растёт от конца памяти данных и структурируется по кадрам. Один кадр состоит из группы элементов, находящихся
10 2 krufter_multiclet
между SP и BP (между вершиной и базой стека). Один элемент кадра является 32-х битной ячейкой памяти.
11 5 krufter_multiclet
Рассмотрим структуру стека при вызове на Си ассемблерной функции типа void, которая не возвращает результат и 
12 6 krufter_multiclet
имеет два аргумента, например *void MDIO_WR(int phy_addr, int reg_num)*:
13 3 krufter_multiclet
14 4 krufter_multiclet
!Stack_void.jpg!
15 5 krufter_multiclet
16 1 krufter_multiclet
Рис 1. Структура стека функции void
17 6 krufter_multiclet
18 6 krufter_multiclet
+Адрес возврата+ - адрес для возвращения обратно в Си программу
19 6 krufter_multiclet
+Аргумент1+ - значение переменной phy_addr
20 6 krufter_multiclet
+Аргумент2+ - значение переменной reg_num
21 6 krufter_multiclet
+Адрес BP+ - значение адреса, по которому располагалась база предыдущего кадра 
22 7 krufter_multiclet
23 7 krufter_multiclet
Вершина стека (SP) находится на 3 позиции выше базы стека (BP).
24 7 krufter_multiclet
25 10 krufter_multiclet
Для функции типа int, которая возвращает результат структура кадра немного изменится(появится поле для возвращаемого значения).
26 8 krufter_multiclet
Например, рассмотрим следующую функцию *int MDIO_RD(int phy_addr, int reg_num)*:
27 8 krufter_multiclet
28 8 krufter_multiclet
!Stack_int.jpg!
29 8 krufter_multiclet
30 12 krufter_multiclet
Рис 2. Структура стека функции int
31 9 krufter_multiclet
32 9 krufter_multiclet
+Адрес возврата+ - адрес для возвращения обратно в Си программу
33 9 krufter_multiclet
+Результат+ - значение возвращаемое функцией в Си
34 9 krufter_multiclet
+Аргумент1+ - значение переменной phy_addr
35 9 krufter_multiclet
+Аргумент2+ - значение переменной reg_num
36 9 krufter_multiclet
+Адрес BP+ - значение адреса, по которому располагалась база предыдущего кадра 
37 9 krufter_multiclet
38 1 krufter_multiclet
Вершина стека (SP) находится на 4 позиции выше базы стека (BP).
39 12 krufter_multiclet
40 12 krufter_multiclet
Стек разумеется можно использовать для своих нужд, но при этом следует учесть, что в ассемблерном файле в котором реализована функция Си
41 12 krufter_multiclet
должно быть сохранение исходных значений вершины и базы стека, а в конце ассемблерного файла их восстановление.
42 14 krufter_multiclet
Рассмотрим пример сохранения исходных значений SP,BP и выделение кадра в размерностью *56/4* (SP-BP), в котором можно разместить 14 своих
43 12 krufter_multiclet
ячеек по 4 байта:
44 12 krufter_multiclet
<pre>
45 12 krufter_multiclet
prologe:
46 12 krufter_multiclet
    getl #SP
47 12 krufter_multiclet
    getl #BP
48 12 krufter_multiclet
    subl @2, 60
49 12 krufter_multiclet
    wrl @2, #SP, -4
50 12 krufter_multiclet
    setl #SP, @2
51 12 krufter_multiclet
    subl @5, 4
52 12 krufter_multiclet
    setl #BP, @1
53 12 krufter_multiclet
    jmp get_put
54 12 krufter_multiclet
complete
55 12 krufter_multiclet
</pre>
56 12 krufter_multiclet
57 12 krufter_multiclet
Для восстановления вершины и базы стека можно использовать следующий универсальный параграф:
58 12 krufter_multiclet
59 12 krufter_multiclet
<pre>
60 12 krufter_multiclet
epiloge:
61 12 krufter_multiclet
    getl #BP
62 12 krufter_multiclet
    addl @1, 4 
63 12 krufter_multiclet
    setl #SP, @1
64 12 krufter_multiclet
    rdl #BP
65 12 krufter_multiclet
    setl #BP, @1
66 12 krufter_multiclet
    rdl RDATA
67 12 krufter_multiclet
    addl @6, 8
68 12 krufter_multiclet
    wrl @2, @1
69 12 krufter_multiclet
    jmp end_ret
70 12 krufter_multiclet
complete
71 12 krufter_multiclet
</pre>
72 12 krufter_multiclet
73 19 krufter_multiclet
Команды getl, setl записывают значение в индексный регистр, а команды wrl, rdl - в память данных по адресу который записан в индексном регистре или получен в результате сложения.
74 13 krufter_multiclet
75 13 krufter_multiclet
!Stack_add.jpg!
76 13 krufter_multiclet
77 14 krufter_multiclet
Рис 3.Выделение кадра в размерностью *56/4*
78 15 krufter_multiclet
79 15 krufter_multiclet
Ознакомиться с примером работы со стеком можно в хранилище в папке LDM_MCP04->Test_time_delay