-
Можно ли отдельно читать байты из памяти?
Пусть у меня есть переменная Integer (4 байт), могу ли я из нее причитать в переменную Word первые или последние 2 байта или байты с 2 по 3 ?
-
кто же кроме тебя-то знает,
можешь ты или нет.
-
Можно, зная адрес можно все, а если и маску знаешь - там еще и биты тебе доступны, включая верхний знаковый
-
> Rouse_ © (20.02.17 13:25) [2]
>
> Можно, зная адрес можно все, а если и маску знаешь - там
> еще и биты тебе доступны, включая верхний знаковый
I: Integer;
W: Word;
Move(I, W, 2);
но нужно как-то так: Move(@I + 2, W, 2);
-
Примерно так:
W:= ((I shr 24) and 0xff) or ((I shr 16) and 0xff)
-
точнее так
W:= (((i shr 8)and $ff) shl 8) or ((i shr 0)and $ff);
-
Чтобы было понятнее:
var i:integer;
a,b,c,d:byte;
w:word;
begin
i:=65535;
a :=(i shr 0) and $ff; //читаем 1-й байт. shr 0 можно убрать.
b:= (i shr 8) and $ff; //2 - й
c:= (i shr 16) and $ff; //3 - й
d:= (i shr 24) and $ff; //4 - й
w:= a or (b shl 8); //объединяем байты - а с нуля, а b сдвигаем на 8 бит.
ShowMessage(IntToStr(a)+' ' +IntToStr(b)+ ' '+IntToStr(c)+' '+IntToStr(d)+' '+IntToStr(w));
end;
-
> [6] stas © (20.02.17 15:58)
Впрос сформулирован в общем, а integer и word для примера. С ними, в частном случае, можно проще, но небезопасно.
-
var pb : pbyte; myinteger, i : integer;
begin
myinteger := MAXINT div 2 -1 ;
pb := @myinteger;
for i := 0 to pred(SizeOf(myinteger)) do ShowMessage(IntToStr((pb+i)^));
-
var
i: integer;
w: word absolute i;
a: array[0..3] of byte absolute i;
-
> rrrrr © (20.02.17 17:02) [8]
> IntToStr((pb+i)^)
IntToStr(PByte(Integer(pb)+i)^)
-
зачем такая ересь?
указатель типизированный.
можно складывать.
крышка разыменует скобки без проблем и вернет байт как и хотелось
-
мало того, но еще и Integer(pb)+i это неправильно.
точнее правильно только для байта.
если требовалось получить word,
то
var pw : pword;
Integer(pw) + 1; //шагнет не на следущее слово, а на все тот же один байт.
то есть на середину.
в отличие от inc(pw);// прыгаем на два байта вперед
-
> rrrrr © (20.02.17 21:03) [11]
> зачем такая ересь?
Чтобы скомпилировалось.
> указатель типизированный.
> можно складывать.
Вопрос про D7. Там нельзя.
-
всю жизнь было можно и вот нельзя
окей,
for i := 0 to pred(SizeOf(myinteger)) do
begin
ShowMessage(IntToStr(pb^));
inc(pb);
end;
-
> rrrrr © (20.02.17 21:22) [14]
Если не ошибаюсь, складывать/вычитать указатель и целое операторами +/- стало можно, начиная с D2009. Inc/Dec - да, работало и в D7.
-
Всегда можно было
-
> Rouse_ © (20.02.17 23:37) [16]
Неверно. Код типа P := P + I, где Р - типизированный указатель, а I - целое, в D7 не компилируется (Operator not applicable to this operand type). Единственное исключение - если Р имеет тип PChar или PWideChar. Об этом даже в справке есть.
Подобная арифметика (и соответствующая ей директива компилятора $POINTERMATH) появилась позже.
-
> Код типа P := P + I, где Р - типизированный указатель, а I - целое, в D7 не компилируется (Operator not applicable to this operand type).
Integer(P):= Integer(P) + 1;
-
> Integer(P):= Integer(P) + 1;
Руки бы тебе оторвать, да поздно.
-
> sniknik © (21.02.17 10:02) [18]
> > Код типа P := P + I, где Р - типизированный указатель,
> а I - целое, в D7 не компилируется (Operator not applicable
> to this operand type).
> Integer(P):= Integer(P) + 1;
какой замечательный код, в 64 битах будет идеально работать :)