Recent

Author Topic: changing an incoming function variable when calculating an internal variable.  (Read 2262 times)

Seenkao

  • Full Member
  • ***
  • Posts: 249
Code: Pascal  [Select][+][-]
  1. procedure memset(dstpp: Pointer; c: byte; len: SizeInt);
  2. var
  3.   i, cccc: LongWord;
  4.   dstp: PBYTE;
  5.   dstpLW: PLongWord;
  6. begin
  7.   if len = 0 then
  8.     exit;
  9.   i := 0;
  10.   dstp := dstpp;
  11.   if (len and 1) > 0 then
  12.   begin
  13.     dstp[i] := c;
  14.     inc(i);
  15.   end;
  16.   len := len shr 1;
  17.   if len = 0 then
  18.     exit;
  19.   if (len and 1) > 0 then
  20.   begin
  21.     dstp[i] := c;
  22.     dstp[i + 1] := c;
  23.     inc(i, 2);
  24.   end;
  25.   len := len shr 1;
  26.   if len = 0 then
  27.     exit;
  28.   dstpLW := dstpp;
  29.   cccc := c + c * $FF + c * $FF00 + c * $FF0000 + c * $FF000000;  // <<<<---- !!!!!
  30.   WriteLn(cccc);
  31.   if (len and 1) > 0 then
  32.   begin
  33.     dstpLW[i] := cccc;
  34.     inc(i, 4);
  35.   end;
  36.   len := len shr 1;
  37.   if len = 0 then
  38.     exit;
  39.   writeln(len);
  40.   while len > 0 do
  41.   begin
  42.     dstpLW[i] := cccc;
  43.     dstpLW[i + 4] := cccc;
  44.     dstpLW[i + 8] := cccc;
  45.     dstpLW[i + 12] := cccc;
  46.     dstpLW[i + 16] := cccc;
  47.     dstpLW[i + 20] := cccc;
  48.     dstpLW[i + 24] := cccc;
  49.     dstpLW[i + 28] := cccc;
  50.     inc(i, 32);
  51.     dec(len);
  52.   end;
  53. end;            
in the line:
cccc := c + c * $FF + c * $FF00 + c * $FF0000 + c * $FF000000;
the variable "C" is reset to zero!
Please check it out!

FPC 3.2.0, Windows 7.

Forgot. Comment out the code located after the specified line. There is an error in the code, there will be a crash.
« Last Edit: September 26, 2021, 12:28:30 am by Seenkao »

Zvoni

  • Hero Member
  • *****
  • Posts: 742
At a guess: You're calling the function with '#0' or '0' as the second parameter.

something multiplied with zero returns zero, zero plus zero is still zero
One System to rule them all, One IDE to find them,
One Code to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
People call me crazy, because i'm jumping out of perfectly fine aircraft

PascalDragon

  • Hero Member
  • *****
  • Posts: 3409
  • Compiler Developer
Do you pass in the pointer to some local variable for dstpp? In that case it can be that you overwrite the stack and thus also where the compiler stores the c variable. And what are you trying to achieve with the c + c * $FF + c * $FF00 + c * $FF0000 + c * $FF000000 anyway? If you want to duplicate c into all four bytes of a 32-bit value then this is the wrong approach.

Thaddy

  • Hero Member
  • *****
  • Posts: 10929
You are overindexing by one.
Try to subtract 1:
Code: Pascal  [Select][+][-]
  1.   cccc := -1+c + c * $FF + c * $FF00 + c * $FF0000 + c * $FF000000;  // <<<< note the -1 at the start
Full:
Code: Pascal  [Select][+][-]
  1. {$MODE objfpc}{$RANGECHECKS ON}
  2. procedure memset(dstpp: Pointer; c: byte; len: SizeInt);
  3. var
  4.   i, cccc: LongWord;
  5.   dstp: PBYTE;
  6.   dstpLW: PLongWord;
  7. begin
  8.   if len = 0 then
  9.     exit;
  10.   i := 0;
  11.   dstp := dstpp;
  12.   if (len and 1) > 0 then
  13.   begin
  14.     dstp[i] := c;
  15.     inc(i);
  16.   end;
  17.   len := len shr 1;
  18.   if len = 0 then
  19.     exit;
  20.   if (len and 1) > 0 then
  21.   begin
  22.     dstp[i] := c;
  23.     dstp[i + 1] := c;
  24.     inc(i, 2);
  25.   end;
  26.   len := len shr 1;
  27.   if len = 0 then
  28.     exit;
  29.   dstpLW := dstpp;
  30.   cccc := -1+c + c * $FF + c * $FF00 + c * $FF0000 + c * $FF000000;  // <<<<---- !!!!!
  31.   WriteLn(cccc);
  32.   if (len and 1) > 0 then
  33.   begin
  34.     dstpLW[i] := cccc;
  35.     inc(i, 4);
  36.   end;
  37.   len := len shr 1;
  38.   if len = 0 then
  39.     exit;
  40.   writeln(len);
  41.   while len > 0 do
  42.   begin
  43.     dstpLW[i] := cccc;
  44.     dstpLW[i + 4] := cccc;
  45.     dstpLW[i + 8] := cccc;
  46.     dstpLW[i + 12] := cccc;
  47.     dstpLW[i + 16] := cccc;
  48.     dstpLW[i + 20] := cccc;
  49.     dstpLW[i + 24] := cccc;
  50.     dstpLW[i + 28] := cccc;
  51.     inc(i, 32);
  52.     dec(len);
  53.   end;
  54. end;  
  55. var
  56.   D:Pointer;
  57. begin
  58.   D := AllocMem(1024);
  59.   MemSet(D,1,1024);
  60. end.
Note that code looks a bit 32 bit centric...
I also do not see the point of that code?
Note the range check will reveal what was wrong. (201)

« Last Edit: September 27, 2021, 09:53:29 am by Thaddy »
The average programmer productivity is 4-5 hours per day. Peak performance 72 hours for short bursts. MTBF is 1 second or less.

Zvoni

  • Hero Member
  • *****
  • Posts: 742
One System to rule them all, One IDE to find them,
One Code to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
People call me crazy, because i'm jumping out of perfectly fine aircraft

Seenkao

  • Full Member
  • ***
  • Posts: 249
PascalDragon, я тестирую код. Это произошло во время тестов. Вполне возможно это не полноценная проверка, возможно я многого не учёл. Вероятно, если бы я использовал переменную "c" в дальнейшем, то я не получил бы её изменения.
В данное время я точно знаю, как быстро дублировать один байт в 4 байта (8 или любое другое количество).
Yandex translate:
Pascal Dragon, I'm testing the code. This happened during the tests. It is quite possible that this is not a full-fledged check, perhaps I did not take into account a lot. Probably, if I had used the variable "c" in the future, I would not have received its changes.
At this time, I know exactly how to quickly duplicate one byte into 4 bytes (8 or any other number of bytes).
Code: Pascal  [Select][+][-]
  1. cccc := c * 1010101;

P.S. Probably I sometimes make hasty conclusions!
« Last Edit: September 27, 2021, 03:42:58 pm by Seenkao »

Zvoni

  • Hero Member
  • *****
  • Posts: 742
Yes, as long as you DON'T call your memset function with something like "memset(SomePointer, 0, SomeSize)"
in your first post in line 29 (where you assign cccc with your formula):
zero multiplied with something is zero, zero plus zero is zero
One System to rule them all, One IDE to find them,
One Code to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
People call me crazy, because i'm jumping out of perfectly fine aircraft

y.ivanov

  • Sr. Member
  • ****
  • Posts: 284
@Seenkao,
cccc := c * $1010101;

Seenkao

  • Full Member
  • ***
  • Posts: 249
Yes, as long as you DON'T call your memset function with something like "memset(SomePointer, 0, SomeSize)"
in your first post in line 29 (where you assign cccc with your formula):
zero multiplied with something is zero, zero plus zero is zero
Нет! Это явно показывает, что вы не пытались даже вникнуть про что я пишу.
В момент вычисления "cccc", "c" сбрасывается в нуль! Даже если входящее значение "c" равно 67 или любому другому числу (не нуль).
Я не учёл в этом моменте, что в дальнейшем "c" не используется. Я просматривал ассемблерный код. И я перепутал паскаль с ассемблером. Компилятор увидел, что "c" больше не используется, и использовал регистр на своё усмотрение, не сохраняя значение "c".

Yandex translate:
No! This clearly shows that you have not even tried to understand what I am writing about.
At the moment of calculating "cccc", "c" is reset to zero! Even if the incoming value of "c" is 67 or any other number (not zero).
I did not take into account at this point that in the future "c" is not used. I was looking through the assembly code. And I confused pascal with assembler. The compiler saw that "c" was no longer used, and used the register at its discretion, without saving the value of "c".

@Seenkao,
cccc := c * $1010101;
Я выше это уже написал.  :)
I have already written this above. :)
« Last Edit: September 27, 2021, 05:00:54 pm by Seenkao »

y.ivanov

  • Sr. Member
  • ****
  • Posts: 284
@Seenkao,
cccc := c * $1010101;
Я выше это уже написал.  :)
I have already written this above. :)
Pls, take note of the added red dollar sign.  :P

Seenkao

  • Full Member
  • ***
  • Posts: 249
Re: changing an incoming function variable when calculating an internal variable.
« Reply #10 on: September 27, 2021, 05:34:47 pm »
Yes, sometimes I'm in a hurry...  :-[

 

TinyPortal © 2005-2018