Конференция "Начинающим" » чтение отдельных байт [D7]
 
  • валя © (20.02.17 12:14) [0]
    Можно ли отдельно читать байты из памяти?
    Пусть у меня есть переменная Integer (4 байт), могу ли я из нее причитать в переменную Word первые или последние 2 байта или байты с 2 по 3 ?
  • rrrrr © (20.02.17 12:22) [1]
    кто же кроме тебя-то знает,
    можешь ты или нет.
  • Rouse_ © (20.02.17 13:25) [2]
    Можно, зная адрес можно все, а если и маску знаешь - там еще и биты тебе доступны, включая верхний знаковый
  • валя © (20.02.17 15:02) [3]

    > Rouse_ ©   (20.02.17 13:25) [2]
    >
    > Можно, зная адрес можно все, а если и маску знаешь - там
    > еще и биты тебе доступны, включая верхний знаковый


    I: Integer;
    W: Word;
    Move(I, W, 2);

    но нужно как-то так:  Move(@I + 2, W, 2);
  • stas © (20.02.17 15:29) [4]
    Примерно так:

    W:= ((I shr 24) and 0xff) or ((I shr 16) and 0xff)
  • stas © (20.02.17 15:37) [5]
    точнее так
    W:= (((i shr 8)and $ff) shl 8) or ((i shr 0)and $ff);
  • stas © (20.02.17 15:58) [6]
    Чтобы было понятнее:
    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;
  • Inovet © (20.02.17 16:31) [7]
    > [6] stas ©   (20.02.17 15:58)

    Впрос сформулирован в общем, а integer и word для примера. С ними, в частном случае, можно проще, но небезопасно.
  • rrrrr © (20.02.17 17:02) [8]
    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)^));
  • sniknik © (20.02.17 17:58) [9]
    var
     i: integer;
     w: word absolute i;
     a: array[0..3] of byte absolute i;

  • Давно не заходил (20.02.17 20:30) [10]
    > rrrrr ©   (20.02.17 17:02) [8]
    > IntToStr((pb+i)^)

    IntToStr(PByte(Integer(pb)+i)^)
  • rrrrr © (20.02.17 21:03) [11]
    зачем такая ересь?

    указатель типизированный.
    можно складывать.
    крышка разыменует скобки без проблем и вернет байт как и хотелось
  • rrrrr © (20.02.17 21:10) [12]
    мало того, но еще и Integer(pb)+i это неправильно.
    точнее правильно только для байта.

    если требовалось получить word,
    то
    var pw : pword;

    Integer(pw) + 1; //шагнет не на следущее слово, а на все тот же один байт.

    то есть на середину.

    в отличие от inc(pw);// прыгаем на два байта вперед
  • Давно не заходил (20.02.17 21:19) [13]
    > rrrrr ©   (20.02.17 21:03) [11]

    > зачем такая ересь?
    Чтобы скомпилировалось.

    > указатель типизированный.
    > можно складывать.
    Вопрос про D7.  Там нельзя.
  • rrrrr © (20.02.17 21:22) [14]
    всю жизнь было можно и вот нельзя

    окей,

    for i := 0 to pred(SizeOf(myinteger)) do
    begin
     ShowMessage(IntToStr(pb^));
     inc(pb);
    end;
  • Давно не заходил (20.02.17 21:30) [15]
    > rrrrr ©   (20.02.17 21:22) [14]

    Если не ошибаюсь, складывать/вычитать указатель и целое операторами +/- стало можно, начиная с D2009. Inc/Dec - да, работало и в D7.
  • Rouse_ © (20.02.17 23:37) [16]
    Всегда можно было
  • Давно не заходил (21.02.17 07:44) [17]
    > Rouse_ ©   (20.02.17 23:37) [16]

    Неверно. Код типа P := P + I, где Р - типизированный указатель, а I - целое, в D7 не компилируется (Operator not applicable to this operand type). Единственное исключение - если Р имеет тип PChar или PWideChar. Об этом даже в справке есть.

    Подобная арифметика (и соответствующая ей директива компилятора $POINTERMATH) появилась позже.
  • sniknik © (21.02.17 10:02) [18]
    > Код типа P := P + I, где Р - типизированный указатель, а I - целое, в D7 не компилируется (Operator not applicable to this operand type).
    Integer(P):= Integer(P) + 1;
  • Игорь Шевченко © (21.02.17 10:22) [19]

    > Integer(P):= Integer(P) + 1;


    Руки бы тебе оторвать, да поздно.
  • Rouse_ © (21.02.17 10:57) [20]

    > 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 битах будет идеально работать :)
 
Конференция "Начинающим" » чтение отдельных байт [D7]
Есть новые Нет новых   [118428   +9][b:0][p:0.001]