он массив читает из сокета, и наверняка объявил его байтовым, соответственно траснслятор поставил вв адресах куда пришлось
Вид для печати
он массив читает из сокета, и наверняка объявил его байтовым, соответственно траснслятор поставил вв адресах куда пришлось
таким кодом у меня получилось перегрузить плк, когда указатель становится не кратным четырем, единственное чего я не добился, чтоб изначально указатель принял не кратное четырем значение, почему это вдруг транслятор, как Вы пишите, должен раздавать адреса на куда попало?Код:VAR
flag : BOOL;
count : INT:=0;
result : REAL;
inPtr : POINTER TO BYTE;
outPtr : POINTER TO REAL;
stuff : ARRAY[0..7] OF BYTE;
tik : TON;
END_VAR
(* @END_DECLARATION := '0' *)
IF tik.Q THEN
inPtr:=ADR(TEMPO);
stuff[count]:=inPtr^;
inPtr:=inPtr+1;
stuff[count+1]:=inPtr^;
inPtr:=inPtr+1;
stuff[count+2]:=inPtr^;
inPtr:=inPtr+1;
stuff[count+3]:=inPtr^;
outPtr:=ADR(stuff[count]);
flag:=NOT DWORD_TO_BOOL(outPtr MOD 4);
(* IF flag THEN*)
result:=outPtr^;
(* END_IF; *)
count:=(count+1) MOD 5;
END_IF;
tik(IN:=NOT tik.Q,PT:=T#2s);
END_FUNCTION_BLOCK
в описании переменных, перед stuff объявите байтовую переменную... у вас объявлены 4 байтные переменные, real и два указателя - транслятор произвел выравнивание, а затем под них вставил байтовый массив, который естественно получился выровненным
:) получается надо писать код неправильно чтоб обрести проблемы :)
Ключевое слово "END_FUNCTION_BLOCK" - т.е. структура где последовательность размещения строго по объяве, поэтому есть автовыравнивание.
В PROGRAM нет обязательного соответствия последовательности объявы и фактического размещения. Предсказать адрес байт-массива не получицца.
ну вобщем то байт перед массивом "помог" перегрузить плк, но теперь вопросов стало еще больше, я как раз рассчитывал на булеву переменную в начале объявления, которая создаст смещение на байт и не даст выполнится кратности для массива. Но оказалось, что совместно с интом она выравняла как раз кратно 4, тогда почему это не сделал добавленный байт. И еще получается что объявленные ПОУ тоже получают адреса кратные четырем, хотя и не проверил на живом плк
Потому что выравнивается каждая (!) переменная соответственно своему типу. Если добавленный байт смещает всё после себя, то смещается всё опять же с выравниванием. Указатели сами по себе 32-битные, и поэтому следующий за outPtr массив stuff окажется на кратном 32 битам адресе. Например, было:Цитата:
я как раз рассчитывал на булеву переменную в начале объявления, которая создаст смещение на байт и не даст выполнится кратности для массива. Но оказалось, что совместно с интом она выравняла как раз кратно 4, тогда почему это не сделал добавленный байт
Поставим байт в начале:Цитата:
DWORD - адрес 0
DWORD - адрес 4
ARRAY OF BYTE - адрес 8
Заметьте, что массив остался выровнен, а на адресах 1-3 образовалась дырка. Попробуем переставить байт к массиву:Цитата:
BYTE - 0
DWORD - 4
DWORD - 8
ARRAY OF BYTE - 12
Вот теперь массив на некратном четырём адресе. Но можно поменять тип массива:Цитата:
DWORD - 0
DWORD - 4
BYTE - 8
ARRAY OF BYTE - 9
Теперь дыра на 9, 10 и 11. Такие дела.Цитата:
DWORD - 0
DWORD - 4
BYTE - 8
ARRAY OF REAL - 12