Лабораторные работы №2 и 3 / lab1
.docСанкт-Петербургский государственный электротехнический университет «ЛЭТИ»
Кафедра МОЭВМ
Лабораторная работа № 1
по дисциплине
«Метрология Программного обеспечения»
Преподаватель: Кирьянчиков В.А.
Выполнилa: Куени Лора
Факультет: КТИ
Группа: 1305
Санкт-Петербург
2005
Для заданного варианта программы обработки данных, представленной на языке Паскаль, разработать вычислительный алгоритм и варианты программ его реализации на языках программи-рования Си и Ассемблер. Добиться, чтобы программы на Паскале и Си были работоспособны и давали корректные результаты (это потребуется в дальнейшем при проведении с ними измерительных экспериментов). Для получения ассемблерного представления программы можно либо самостоятельно написать код на ассемблере, реализующий заданный алгоритм, либо установить опцию "Code generation/Generate assembler source" при компиляции текста программы, представленной на языке Си. При этом в ассемблерном представлении программы нужно удалить директивы описаний и отладочные директивы, оставив только исполняемые операторы.
Примечание!
******************************************************************
В заданных на Паскале вариантах программ обработки данных важен только вычислительный алгоритм, реализуемый программой. Поэтому для получения более корректных оценок характеристик программ следует учитывать только вычислительные операторы и по возможности исключить операторы, обеспечивающие интерфейс с пользователем и выдачу текстовых сообщений.
В сути алгоритма, реализуемого программой, нужно разобраться достаточно хорошо для возможности внесения в программу модификаций, выполняемых в дальнейшем с целью проведения измерений и улучшения характеристик качества программы.
Для измеряемых версий программ в дальнейшем нужно будет исключить операции ввода данных с клавиатуры и вывода на печать, потребляющие основную долю ресурса времени при выполнении программы. Поэтому можно уже в этой работе предусмотреть соответствующие преобразования исходной программы.
******************************************************************
Для каждой из разработанных программ (включая исходную прог-рамму на Паскале) определить следующие метрические характеристики (по Холстеду):
1. Измеримые характеристики программ:
- число простых(отдельных)операторов, в данной реализации;
- число простых (отдельных) операндов, в данной реализации;
- общее число всех операторов в данной реализации;
- общее число всех операндов в данной реализации;
- число вхождений j-го оператора в тексте программы;
- число вхождений j-го операнда в тексте программы;
- словарь программы;
- длину программы.
2. Расчетные характеристики программы:
- длину программы;
- реальный, потенциальный и граничный объемы программы;
- уровень программы;
- интеллектуальное содержание программы;
- работа программиста;
- время программирования;
- уровень используемого языка программирования;
-
ожидаемое число ошибок в программе.
Для каждой характеристики следует рассчитать как саму харак-теристику, так и ее оценку.
Расчет оценок программ выполнить двумя способами:
1) вручную или с помощью одного из доступных пакетов математических вычислений DERIVE, MATHCAD или MATLAB.
2) с помощью программы автоматизации расчета метрик Холстеда, краткая инструкция по работе с которой приведена в файле usage.rtf (для С- и Паскаль-версий программ).
Для варианта расчета с использованием программы автоматизации желательно провести анализ влияния учета тех или иных групп операторов исследуемой программы на вычисляемые характеристики за счет задания разных ключей запуска.
Результаты расчетов представить в виде таблиц с текстовыми комментариями.
Паскаль
{Программа 11. Интегрирование методом Симпсона.}
program simp1;
{ integration by Simpson's method }
{ Turbo Pascal cannot pass function names as arguments}
uses crt;
const tol = 1.0E-6;
var sum,upper,lower : real;
function fx(x: real): real;
{ find f(x)=1/x }
{ watch out for x=0 }
begin
fx:=1.0/x
end; { function fx }
procedure simps(
lower,upper,tol : real;
var sum : real);
{ numerical integration by Simpson's rule }
{ function is fx, limits are lower and upper }
{ with number of regions equal to pieces }
{ partition is delta_x, answer is sum }
var i : integer;
x,delta_x,even_sum,
odd_sum,end_sum,
sum1 : real;
pieces : integer;
begin
pieces:=2;
delta_x:=(upper-lower)/pieces;
odd_sum:=fx(lower+delta_x);
even_sum:=0.0;
end_sum:=fx(lower)+fx(upper);
sum:=(end_sum+4.0*odd_sum)*delta_x/3.0;
writeln(pieces:5,sum);
repeat
pieces:=pieces*2;
sum1:=sum;
delta_x:=(upper-lower)/pieces;
even_sum:=even_sum+odd_sum;
odd_sum:=0.0;
for i:=1 to pieces div 2 do
begin
x:=lower+delta_x*(2.0*i-1.0);
odd_sum:=odd_sum+fx(x)
end;
sum:=(end_sum+4.0*odd_sum+2.0*even_sum)*delta_x/3.0;
writeln(pieces:5,sum)
until (sum<>sum1) and (abs(sum-sum1)<=abs(tol*sum))
end; { simps }
begin { main program }
clrscr;
lower:=1.0;
upper:=9.0;
writeln;
simps(lower,upper,tol,sum);
writeln;
writeln(chr(7),'area= ',sum);
readkey;
end.
Си++
#include<conio.h>
#include<stdio.h>
#include<stdlib.h>
#include<iostream.h>
#include <time.h>
const tol = 1.0E-6;
float sum,upper,lower ;
float fx(float x)
{
float tmp;
tmp =1.0 /x ;
return tmp ;
}
void simps(float lower,float upper,float tol,float sum )
{
int i ;
float x,delta_x,even_sum,odd_sum,end_sum,sum1 ;
int pieces ;
pieces=2;
delta_x = (upper-lower)/pieces;
odd_sum = fx(lower+delta_x);
even_sum = 0.0;
end_sum = fx(lower)+fx(upper);
sum = (end_sum+4.0*odd_sum)*delta_x/3.0;
cout<<"pieces="<<sum<<endl;
do
{
odd_sum=0.0;
for (i=1;i<= pieces/2;i++ )
{
x=lower+delta_x*(2.0*i-1.0);
odd_sum=odd_sum+fx(x) ;
};
pieces=pieces*2;
sum1=sum;
delta_x=(upper-lower)/pieces;
even_sum=even_sum+odd_sum;
sum=(end_sum+4.0*odd_sum+2.0*even_sum)*delta_x/3.0;
cout<<"pieces="<<sum;
}
while ((sum == sum1) || (abs(sum-sum1)<=abs(tol*sum)));
}; // { simps }
void main () // { main program }
{
clrscr();
lower=1.0;
upper=9.0;
cout<<endl;
simps(lower,upper,tol,sum);
cout<<endl;
cout<<"area="<<sum;
getche();
}
Ассемблер
-
Текст программы
@fx$qf proc near
push bp
mov bp,sp
sub sp,4
fld dword ptr [bp+4]
fld1
fdivr
fstp dword ptr [bp-4]
fld dword ptr [bp-4]
jmp short @1@58
@1@58:
mov sp,bp
pop bp
ret
@fx$qf endp
@simps$qffff proc near
push bp
mov bp,sp
sub sp,36
push si
push di
mov si,2
mov word ptr [bp-26],si
fild word ptr [bp-26]
fld dword ptr [bp+8]
fsub dword ptr [bp+4]
fdivr
fstp dword ptr [bp-8]
fld dword ptr [bp+4]
fadd dword ptr [bp-8]
sub sp,4
fstp dword ptr [bp-44]
fwait
call near ptr @fx$qf
pop cx
pop cx
fstp dword ptr [bp-16]
fwait
mov word ptr [bp-10],0
mov word ptr [bp-12],0
fld dword ptr [bp+4]
sub sp,4
fstp dword ptr [bp-44]
fwait
call near ptr @fx$qf
pop cx
pop cx
fstp tbyte ptr [bp-36]
fld dword ptr [bp+8]
sub sp,4
fstp dword ptr [bp-44]
fwait
call near ptr @fx$qf
pop cx
pop cx
fld tbyte ptr [bp-36]
fadd
fstp dword ptr [bp-20]
fld dword ptr [bp-20]
fld dword ptr [bp-16]
fmul dword ptr DGROUP:s@
fadd
fmul dword ptr [bp-8]
fdiv dword ptr DGROUP:s@+4
fstp dword ptr [bp+16]
mov ax,offset @endl$qr7ostream
push ax
fld dword ptr [bp+16]
sub sp,4
fstp dword ptr [bp-46]
mov ax,offset DGROUP:s@+8
push ax
mov ax,offset DGROUP:_cout
push ax
fwait
call near ptr @@ostream@$blsh$qpxzc
pop cx
pop cx
push ax
call near ptr @@ostream@$blsh$qf
add sp,6
push ax
call near ptr @@ostream@$blsh$qpqr7ostream$r7ostream
pop cx
pop cx
@2@58:
mov word ptr [bp-14],0
mov word ptr [bp-16],0
mov di,1
jmp short @2@142
@2@86:
fld dword ptr [bp-8]
mov word ptr [bp-26],di
fild word ptr [bp-26]
fmul dword ptr DGROUP:s@+16
fld1
fsub
fmul
fadd dword ptr [bp+4]
fstp dword ptr [bp-4]
fld dword ptr [bp-4]
sub sp,4
fstp dword ptr [bp-44]
fwait
call near ptr @fx$qf
pop cx
pop cx
fadd dword ptr [bp-16]
fstp dword ptr [bp-16]
fwait
inc di
@2@142:
mov ax,si
cwd
sub ax,dx
sar ax,1
cmp ax,di
jge short @2@86
mov ax,si
shl ax,1
mov si,ax
mov ax,word ptr [bp+18]
mov dx,word ptr [bp+16]
mov word ptr [bp-22],ax
mov word ptr [bp-24],dx
mov word ptr [bp-26],si
fild word ptr [bp-26]
fld dword ptr [bp+8]
fsub dword ptr [bp+4]
fdivr
fstp dword ptr [bp-8]
fld dword ptr [bp-12]
fadd dword ptr [bp-16]
fstp dword ptr [bp-12]
fld dword ptr [bp-20]
fld dword ptr [bp-16]
fmul dword ptr DGROUP:s@
fadd
fld dword ptr [bp-12]
fmul dword ptr DGROUP:s@+16
fadd
fmul dword ptr [bp-8]
fdiv dword ptr DGROUP:s@+4
fstp dword ptr [bp+16]
fld dword ptr [bp+16]
sub sp,4
fstp dword ptr [bp-44]
mov ax,offset DGROUP:s@+20
push ax
mov ax,offset DGROUP:_cout
push ax
fwait
call near ptr @@ostream@$blsh$qpxzc
pop cx
pop cx
push ax
call near ptr @@ostream@$blsh$qf
add sp,6
fld dword ptr [bp+16]
fcomp dword ptr [bp-24]
fstsw word ptr [bp-26]
fwait
mov ax,word ptr [bp-26]
sahf
jne @@4
jmp @2@58
@@4:
fld dword ptr [bp+16]
fsub dword ptr [bp-24]
call near ptr N_FTOL@
push ax
call near ptr @abs
pop cx
push ax
fld dword ptr [bp+12]
fmul dword ptr [bp+16]
call near ptr N_FTOL@
push ax
call near ptr @abs
pop cx
pop dx
cmp dx,ax
jg @@5
jmp @2@58
@@5:
pop di
pop si
mov sp,bp
pop bp
ret
@simps$qffff endp
_main proc near
push bp
mov bp,sp
?debug B
call near ptr _clrscr
mov word ptr DGROUP:_lower+2,16256
mov word ptr DGROUP:_lower,0
mov word ptr DGROUP:_upper+2,16656
mov word ptr DGROUP:_upper,0
mov ax,offset @endl$qr7ostream
push ax
mov ax,offset DGROUP:_cout
push ax
call near ptr @@ostream@$blsh$qpqr7ostream$r7ostream
pop cx
pop cx
fld dword ptr DGROUP:_sum
sub sp,4
fstp dword ptr [bp-4]
fldz
fwait
sub sp,4
fstp dword ptr [bp-8]
fld dword ptr DGROUP:_upper
sub sp,4
fstp dword ptr [bp-12]
fld dword ptr DGROUP:_lower
sub sp,4
fstp dword ptr [bp-16]
fwait
call near ptr @simps$qffff
add sp,16
mov ax,offset @endl$qr7ostream
push ax
mov ax,offset DGROUP:_cout
push ax
call near ptr @@ostream@$blsh$qpqr7ostream$r7ostream
pop cx
pop cx
fld dword ptr DGROUP:_sum
sub sp,4
fstp dword ptr [bp-4]
mov ax,offset DGROUP:s@+28
push ax
mov ax,offset DGROUP:_cout
push ax
fwait
call near ptr @@ostream@$blsh$qpxzc
pop cx
pop cx
push ax
call near ptr @@ostream@$blsh$qf
add sp,6
call near ptr _getche
pop bp
ret
_main endp
_TEXT ends
@@ostream@$blsh$qpxzc proc near
push bp
mov bp,sp
push si
mov si,word ptr [bp+4]
xor ax,ax
push ax
push word ptr [bp+6]
push si
call near ptr @ostream@outstr$qpxzct1
add sp,6
mov ax,si
jmp short @4@58
@4@58:
pop si
pop bp
ret
@@ostream@$blsh$qf proc near
push bp
mov bp,sp
push si
mov si,word ptr [bp+4]
fld dword ptr [bp+6]
sub sp,10
fstp tbyte ptr [bp-12]
push si
fwait
call near ptr @ostream@$blsh$qg
add sp,12
jmp short @5@58
@5@58:
pop si
pop bp
ret
push bp
mov bp,sp
push si
mov si,word ptr [bp+4]
push si
call word ptr [bp+6]
pop cx
jmp short @6@58
@6@58:
pop si
pop bp
ret
assume cs:_TEXT
@abs proc near
push bp
mov bp,sp
mov ax,word ptr [bp+4]
cwd
xor ax,dx
sub ax,dx
jmp short @7@58
@7@58:
pop bp
ret
@abs endp
Метрические характеристики
Для языка Паскаль можно воспользоваться программами автоматизации расчёта метрических характеристик по Холстеду Parser_Pas.exe и Metrics.exe. Ниже приведены результаты работы программы Metrics.exe
Operators:
|
Operands:
|
| 1 | 18 | () | 2 | 9 | * | 3 | 8 | + | 4 | 4 | - | 5 | 6 | / | 6 | 47 | ; | 7 | 1 | <= | 8 | 1 | <> | 9 | 18 | = | 10 | 2 | abs | 11 | 1 | and | 12 | 1 | const | 13 | 1 | for | 14 | 1 | function | 15 | 5 | fx | 16 | 2 | integer | 17 | 1 | procedure | 18 | 1 | program | 19 | 6 | real | 20 | 1 | repeat | 21 | 2 | simps | 22 | 5 | writeln |
| 1 | 2 | 0.0 | 2 | 1 | 1 | 3 | 3 | 1.0 | 4 | 1 | 1.0E-6 | 5 | 3 | 2 | 6 | 2 | 2.0 | 7 | 2 | 3.0 | 8 | 2 | 4.0 | 9 | 2 | 5 | 10 | 1 | 7 | 11 | 1 | 9.0 | 12 | 7 | delta_x | 13 | 4 | end_sum | 14 | 5 | even_sum | 15 | 1 | fx | 16 | 2 | i | 17 | 9 | lower | 18 | 8 | odd_sum | 19 | 9 | pieces | 20 | 1 | simp1 | 21 | 12 | sum | 22 | 4 | sum1 | 23 | 4 | tol | 24 | 7 | upper | 25 | 5 | x |
Summary:
=====================================
The number of different operators : 22
The number of different operands : 25
The total number of operators : 141
The total number of operands : 99
Dictionary ( D) : 47
Length ( N) : 240
Length estimation ( ^N) : 226.253
Volume ( V) : 1333.1013
Potential volume ( *V) :15.5097 19.6515 получено для eta=5
Limit volume (**V) : 25.8496
Programming level ( L) : 0,0180
Programming level estimation ( ^L) : 0,0230
Intellect ( I) : 30,6038
Time of programming ( T) : 7404,8298
Time estimation ( ^T) : 5806,9894
Programming language level (lambda) : 0,4321
Work on programming ( E) : 74048,2975
Error ( B) : 0,4444
Для языка Си можно воспользоваться программами автоматизации расчёта метрических характеристик по Холстеду Parser_C.exe и Metrics.exe. Ниже приведены результаты работы программы Metrics.exe:
Operators:
|
Operands:
|
| 1 | 11 | () | 2 | 9 | * | 3 | 8 | + | 4 | 1 | ++ | | | | 5 | 4 | - | 6 | 6 | / | 7 | 5 | << | 8 | 2 | <= | 9 | 17 | = | 10 | 1 | == | 11 | 2 | abs | 12 | 1 | dowhile | 13 | 1 | for | 14 | 5 | fx | 15 | 1 | return | 16 | 1 | simps | 17 | 1 | || |
| 1 | 2 | 0.0 | 2 | 1 | 1 | 3 | 2 | 1.0 | 4 | 1 | 1.0E-6 | 5 | 3 | 2 | 6 | 2 | 2.0 | 7 | 2 | 3.0 | 8 | 2 | 4.0 | 9 | 2 | | 10 | 7 | delta_x | 11 | 4 | end_sum | 12 | 1 | endl | 13 | 5 | even_sum | 14 | 5 | i | 15 | 7 | lower | 16 | 8 | odd_sum | 17 | 7 | pieces | 18 | 10 | sum | 19 | 4 | sum1 | 20 | 3 | tmp | 21 | 3 | tol | 22 | 5 | upper | 23 | 5 | x |
Summary:
The number of different operators : 17
The number of different operands : 23
The total number of operators : 76
The total number of operands : 91
Dictionary ( D) : 40
Length ( N) : 167
Length estimation ( ^N) : 173,5288
Volume ( V) : 888,7620
Potential volume ( *V) : 15.5097
Limit volume (**V) : 25.8496
Programming level ( L) : 0,0270
Programming level estimation ( ^L) : 0,0297
Intellect ( I) : 26,4273
Time of programming ( T) : 3291,2412
Time estimation ( ^T) : 2988,9452
Programming language level (lambda) : 0,6481
Work on programming ( E) : 32912,4116
Error ( B) : 0,2963
К сожалению, программных средств автоматизации подсчёта метрических характеристик для языка Ассемблера найти не удалось, поэтому все метрики были посчитаны вручную. Результаты этой занимательной работы приведены ниже
Операторы
№ |
Оператор |
f1j |
1 |
shl-- |
1 |
2 |
Push-- |
35 |
3 |
Pop-- |
35 |
4 |
Proc-- |
6 |
5 |
fmul-- |
8 |
6 |
jg-- |
1 |
7 |
Jge |
1 |
8 |
fadd-- |
8 |
9 |
fwait-- |
13 |
10 |
Ret-- |
7 |
11 |
Xor-- |
2 |
12 |
fstp-- |
23 |
13 |
Fld-- |
26 |
14 |
add-- |
6 |
15 |
fld1 -- |
2 |
16 |
fild-- |
3 |
17 |
cmp-- |
2 |
18 |
fdivr-- |
3 |
19 |
cwd-- |
2 |
20 |
Jmp @1@58-- |
1 |
21 |
fsub-- |
4 |
23 |
Sahf-- |
1 |
24 |
fdiv-- |
2 |
25 |
jmp @2@58-- |
2 |
26 |
jmp @4@58-- |
1 |
27 |
jmp @5@58 |
1 |
28 |
jmp @6@58 |
1 |
29 |
Jmp @7@58 |
1 |
30 |
Call near ptr @fx$qf |
4 |
31 |
Call near ptr @@ostream@$blsh$qpxzc |
3 |
32 |
call near ptr @@ostream@$blsh$qpqr7ostream$r7ostream
|
3 |
33 |
call word ptr [bp+6] |
1 |
34 |
Call near ptr @Simps$qfff |
1 |
35 |
Call near ptr _clrscr |
1 |
36 |
Call near ptr _getche |
1 |
37 |
Call near ptr @ abs |
2 |
38 |
Fld-- |
26 |
39 |
call near ptr N_FTOL@ |
2 |
40 |
fldz-- |
1 |
41 |
Inc-- |
1 |
42 |
Sub-- |
16 |
43 |
fstsw-- |
1 |
|
|
|
Операнды
№ |
Операнд |
f1i |
1 |
ax-- |
47 |
2 |
Sp-- |
29 |
3 |
[bp+8] -- |
3 |
4 |
[bp-10]-- |
1 |
5 |
[bp+4]-- |
10 |
6 |
[bp-4]-- |
6 |
7 |
[bp-20]-- |
3 |
8 |
[bp-26] |
8 |
9 |
[bp-16] |
8 |
10 |
[bp-36] |
2 |
11 |
[bp-44] |
5 |
12 |
[bp-24] |
3 |
13 |
[bp+18] |
1 |
14 |
[bp+16] |
8 |
15 |
[bp+12]-- |
1 |
16 |
[bp-12]-- |
6 |
17 |
[bp-8]-- |
7 |
18 |
[bp-46]-- |
1 |
19 |
[bp-14]-- |
1 |
20 |
[bp-22]-- |
1 |
21 |
[bx+2]-- |
3 |
22 |
[bp+6]-- |
3 |
23 |
[bp+10]-- |
5 |
24 |
Sp
|
29 |
25 |
[bx] |
24 |
26 |
cx-- |
23 |
27 |
DGROUP:_lower+2,16256 |
1 |
28 |
DGROUP:_upper+2,16656 |
1 |
29 |
si-- |
21 |
30 |
Di |
6 |
31 |
DGROUP:_lower |
3 |
32 |
DGROUP:_upper |
3 |
33 |
DGROUP:_cout |
5 |
34 |
DGROUP:s@ |
2 |
35 |
DGROUP:s@+4 |
2 |
36 |
DGROUP:s@+8 |
1 |
37 |
DGROUP:s@+16 |
2 |
38 |
DGROUP:s@+28 |
1 |
39 |
DGROUP:_sum |
2 |
40 |
dx-- |
7 |
41 |
1 |
3 |
42 |
2 |
1 |
43 |
4 |
12 |
44 |
10 |
1 |
45 |
12 |
1 |
46 |
16 |
1 |
47 |
36 |
1 |
48 |
0 |
6 |