>... А вот читается этот код конкретно тяжелее ...
Да, чтение листинга программы на ассемблере дело не для слабонервных. Но если структурировать, выделить и собрать код в подпрограммы и создать библиотеки с хорошим описанием назначения подпрограммы (функции), описать входные и выходные параметры, то можно работать, например в случае бортовых систем.
Но и чтение листинга программы на SIMATIC SCL тоже не вдохновляет. Чтобы быть правильно понятым, приведу листинги двух функционально тождественных программ:
На STL
Код: Выделить всё
FUNCTION "DItoWTS" : WORD
//TITLE =
//-- Формируем локальный вектор wTS из системного DI.
AUTHOR : Burlak
FAMILY : STL_LM
NAME : DItoWTS
VERSION : 01.00
VAR_INPUT
N : INT; //-- Размер локального вектора дискретных входов
vecAdr : POINTER; //-- Указатель на вектор адресов дискретных входов
END_VAR
VAR_TEMP
i : INT; //-- Параметр цикла
DB_NO : WORD; //-- Номер блока данных
SysDI : DWORD; //-- Указатель на системный вектор дискретных входов
wx : WORD; //-- Сдвиг единицы
v : WORD; //-- Динамика результата
END_VAR
BEGIN
L P#vecAdr; LAR1; //-- Косвенный доступ к POINTER
L W[AR1,P#0.0]; T DB_NO; //-- Получим номер блока данных
OPN DB[DB_NO]; //-- Откроем блок данных (DB or NOP)
L D[AR1, P#2.0]; LAR1; //-- Адрес вектора адресов бит вектора дискретных входов процесса
L 1; T wx; //-- Храним сдвиг единицы
L 0; T v; //-- Начальное значение
L N; //-- Параметр цикла - размер локального вектора дис. состояния
Cicl:
T #i; //-- i <-- ACCU1
L W[AR1,P#0.0]; T SysDI; //-- SysDI:=адрес бита вектора дискретных входов процесса
SET; A I[SysDI]; //-- Получим значение дискретного хода процесса
JCN Prod;
L wx; L v; OW; T v; //-- Обработка, если единица (true)
Prod:
+AR1 P#2.0; //-- Следующая компонента вектора адресов
L wx; SLW 1; T wx; //-- Сдвиг единицы влево
L #i;
LOOP Cicl; //-- Цикл DO..END
L v; T RET_VAL;
BE;
END_FUNCTION
Код: Выделить всё
//======================================================
TYPE "UDT_ANY"
TITLE ='структура ANY-указателя'
FAMILY : 'LIB_PTR'
AUTHOR : Mayasin
VERSION: 1.0
STRUCT
id: BYTE; //код
tp: BYTE; //тип
sz: INT; //размер
blk: WORD; //номер блока данных
area: DWORD; //указатель на область
END_STRUCT
END_TYPE
//-------------------------------------------
FUNCTION DItoWTS : WORD
TITLE = 'формирование локального вектора текущего дискретного состояния'
FAMILY: LIB_LM
VERSION : '1.0'
AUTHOR : Mayasin_Burlak
VAR_INPUT
N : INT; //-- Размер локального вектора дискретных входов
vecAdr : ANY; //-- Указатель на вектор адресов дискретных входов
END_VAR
VAR_TEMP
i : INT; //-- Параметр цикла
j : INT; //-- Индекс байта
k : INT; //-- Индекс бита
l : INT; //-- Номер бита в системном векторе дискретного состояния
w : INT; //-- Сдвиг единицы
v : WORD; //-- Результат
s : INT; //-- Смещение в verAdr
//укзатели в виде структур
pva: ANY;
ptr AT pva: UDT_ANY;
END_VAR
BEGIN
w :=1;
v :=0;
i :=0;
pva := vecAdr;
s := DWORD_TO_INT(SHR(in:=SHL(in:=ptr.area, n:=8),n:=11));
WHILE (i < N) DO
l:=WORD_TO_INT(WORD_TO_BLOCK_DB(ptr.blk).dw[s]);
k:=l MOD 8;
j:=l DIV 8;
IF I[j,k]=1 THEN
v:=v OR INT_TO_WORD(w);
END_IF;
w:=w*2;
s:=s+2;
i:=i+1;
END_WHILE;
DItoWTS:=v;
END_FUNCTION
Большой разницы в читабельности этих текстов я не нахожу, но если код на ассемблере два раза компактнее и на порядок быстрее, то можно, затратив несколько больше времени, написать инструкции абстрактной машины и на ассемблере, например, для бортовых систем. Ничего криминального в этом нет.
С уважением, Владимир.
p.s. Помогать или не помогать мне, это личное дело каждого