Uploaded by Евгений Поминов

Laba 2 micro

advertisement
Федеральное государственное автономное
образовательное учреждение
высшего образования
«СИБИРСКИЙ ФЕДЕРАЛЬНЫЙ УНИВЕРСИТЕТ»
ИИФиРЭ
институт
Радиоэлектронная техника информационных систем
кафедра
СХЕМОТЕХНИКА ЦИФРОВЫХ УСТРОЙСТВ
ОТЧЕТ ПО ЛАБОРАТОРНОЙ РАБОТЕ №2
Изучение функций и процедур
В - 15
Руководитель
Батурин Т. H.
подпись, дата
Студент РФ18-32Б
код (номер) группы,
инициалы, фамилия
Поминов Е. И.
подпись, дата
Красноярск 2022
инициалы, фамилия
СОДЕРЖАНИЕ
ВВЕДЕНИЕ .............................................................................................................. 2
ЗАКЛЮЧЕНИЕ ....................................................................................................... 3
ПРИЛОЖЕНИЕ А ................................................................................................... 4
ПРИЛОЖЕНИЕ Б .................................................................................................... 5
ПРИЛОЖЕНИЕ В ................................................................................................... 7
ВВЕДЕНИЕ
Цель работы: освоение инструкций ассемблера микропроцессора
Cortex-M3 и программной среды Keil MDK.
Задача работы:

Выполнить задание (написать программу расчета среднего
арифметического значения отрицательных элементов в одномерном массиве,
заменить минимальный элемент в одномерном массиве на среднее
арифметическое) на языке Си используя функции и указатели.

Переписать программу с помощью процедур языка ассемблера.

Вызвать процедуры, написанные на ассемблере в коде на языке
Си.

Сравнить результат выполнения функций на языке Си и на языке
ассемблера.
2
ЗАКЛЮЧЕНИЕ
В ходе выполнения работы, был закреплены навыки программирования
на языке ассемблер. На основе проделанной работы был сделан вывод, что,
язык программирования ассемблер, является языком программирования
низкого уровня, вследствие чего, программы, написанные на языке
ассемблер, выполняются быстрее чем программы написанные например на
языке программирования СИ, но в таких программах легко запутаться, что
является нежелательным влиянием, но так же есть и положительный фактор,
на языке ассемблера можно осуществить разграничение выполнения
действий. В программах на СИ в свою очередь, запутаться труднее,
поскольку можно создавать разного рода блоки, а так же для составления
разного рода условий и циклов, не обязательно использовать команды
переходов. Язык СИ можно связывать с языком Ассемблер, в следствии чего,
появляется более большая возможность для выполнения разного рода
операций. Результат сравнения приведен на рисунке 1. 1 строка, результат
выполнения в ассемблере; 5 строка, выполнение в СИ.
Рисунок 1 – Инициализированные и измененные массивы
3
ПРИЛОЖЕНИЕ А
Стартовой программный код
Stack_Size
Stack_Mem
__initial_sp
EQU
0x400
AREA
SPACE
STACK, NOINIT, READWRITE, ALIGN=3
Stack_Size
; <h> Heap Configuration
;
<o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>
Heap_Size
__heap_base
Heap_Mem
__heap_limit
EQU
0x200
AREA
HEAP, NOINIT, READWRITE, ALIGN=3
SPACE
Heap_Size
PRESERVE8
THUMB
; Vector Table Mapped to Address 0 at Reset
AREA
RESET, DATA, READONLY
DCD
__initial_sp
DCD
Reset_Handler
AREA
; Reset handler
Reset_Handler
PROC
IMPORT __main
LDR
BX
;
ENDP
; Top of Stack
; Reset Handler
|.text|, CODE, READONLY
R0, =__main
R0
B main_asm
IMPORT
EXPORT
__use_two_region_memory
__user_initial_stackheap
__user_initial_stackheap
LDR
LDR
LDR
LDR
BX
R0,
R1,
R2,
R3,
LR
= Heap_Mem
=(Stack_Mem + Stack_Size)
= (Heap_Mem + Heap_Size)
= Stack_Mem
ALIGN
END
;************************
FILE*****
(C)
COPYRIGHT
4
STMicroelectronics
*****END
OF
ПРИЛОЖЕНИЕ Б
Программный код СИ
#include <stdint.h>
/*
Заголовочный
файл
объявляет
несколько
целочисленных типов и макросов */
/*
ЗАДАНИЕ:
15 Сфомировать массив элементы которогшо будут равны полусумме соседних
элементов
*/
// Инициализируем первичный массив с числами
int32_t array_original [] = {0, 2, 7, 8, 4, 9, -3, 6, 4 ,3};
// Инициализируем указатель на новый массив. Начальное значение NULL
int32_t* array = NULL;
// Объявляем прототип функции, которая будет выполнять задание
int32_t* array_do (int32_t* array_ptr, size_t array_size);
//Экспортируем функцию из Laba_2.s написанную на ассемблере.
extern void Laba_2 (int32_t* array_ptr, int32_t* new_array_ptr,
array_size );
size_t
// Объявляем мпустой массив для передачи его адреса в функцию Laba_2
int32_t new_array [sizeof(array_original)/sizeof(int32_t)]= {0};
int main (void)
{
/*Вызываем функцию array_do.
Функция возвратит указатель на массив соответствующий заданию.
Размерность массива такая же как у оригинального массива.*/
array
=
sizeof(array_original)/sizeof(int32_t));
array_do(array_original,
/*Вызываем функцию Laba_2, тело которой описано в файле Laba_2.s.
Так как, в языке ассемблера не функций malloc() и вообще нет механизма
выделения данных из кучи,
то мы заранее выделяем место в оперативной памяти для обработанного
массива,
поэтому нам необходимо передать адрес нового массива в функцию.
Размерность массива такая же как у оригинального массива.*/
Laba_2(array_original,
sizeof(array_original)/sizeof(int32_t));
new_array,
while (1)
{
}
return 0;
}
/****************************************************************************
****/
/* new_array[], в котором элементы равны полусумме двух соседних элементов
элементов массива array_original[] .*/
/****************************************************************************
****/
/*
Функция принимает:
int32_t* array_ptr - указатель на исходный массив с элементами типа
int32_t
5
array_size
- размер массива
Функция возвращает:
указатель на область памяти в котором лежит новый массив
*/
int32_t* array_do (int32_t* array_ptr, size_t array_size)
{
int32_t *new_array = NULL;
int32_t k=2;
int32_t m=1;
int32_t b=10;
int32_t j=0;
//Выделяем область памяти для нового массива из кучи (heap).
new_array = (int32_t*) (malloc(array_size));
for (uint32_t i = 0; i <= array_size;)
{
if (i==array_size)
{
m=array_size;
j=1;}
else
*(new_array+i) = (*(array_ptr+(i-m))+*(array_ptr+i))/k;
*(new_array+i) = (*(array_ptr+(i-m))+*(array_ptr+(i-j)))/k;
i++;
}
return new_array;
6
ПРИЛОЖЕНИЕ В
Программный код ассемблера
GET stm32_EQU.s
; Объявляем сегмент кода
AREA MAIN, CODE, READONLY
THUMB
; Объявляем функцию main
к
; R0 adress vhod
; R1 adress vihod
; R2 kolvo element
; R3 ykazatel massiv
; R4 tek element
; R5 next element
; R6 polosumma
; R7 ykazivat na razmer(delitel)
Laba_2
PROC
EXPORT Laba_2
PUSH {R3,R4,R5,R6,R7,R14}
MOV R7,#FOUR
MUL R2,R2,R7
SUB R2,#FOUR
MOV R3,#NULL
MOV R7,#2
while
LDR R4,[R0,R3]
ADD R3,#FOUR
LDR R5,[R0,R3]
ADD R6,R4,R5
SDIV R6,R6,R7
SUB R3,#FOUR
STR R6,[R1,R3]
ADD R3,#FOUR
CMP R3,R2
BLT while
LDR R4,[R0,R3]
LDR R5,[R0,#NULL]
ADD R6,R4,R5
SDIV R6,R6,R7
STR R6,[R1,R3]
POP {R3,R4,R5,R6,R7,R14}
BX LR
ENDP ; Конец функции main
END
; Конец файла
7
Download