Bookstore

 Computer Math and Games in Pascal (preview) Lazarus Handbook

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

Seenkao

• Sr. Member
• Posts: 261
changing an incoming function variable when calculating an internal variable.
« on: September 26, 2021, 12:18:20 am »
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!

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: 805
Re: changing an incoming function variable when calculating an internal variable.
« Reply #1 on: September 27, 2021, 09:11:00 am »
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 Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

PascalDragon

• Hero Member
• Posts: 3505
• Compiler Developer
Re: changing an incoming function variable when calculating an internal variable.
« Reply #2 on: September 27, 2021, 09:11:21 am »
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.

• Hero Member
• Posts: 10991
Re: changing an incoming function variable when calculating an internal variable.
« Reply #3 on: September 27, 2021, 09:36:49 am »
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: 805
Re: changing an incoming function variable when calculating an internal variable.
« Reply #4 on: September 27, 2021, 10:42:03 am »
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

Seenkao

• Sr. Member
• Posts: 261
Re: changing an incoming function variable when calculating an internal variable.
« Reply #5 on: September 27, 2021, 03:39:02 pm »
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: 805
Re: changing an incoming function variable when calculating an internal variable.
« Reply #6 on: September 27, 2021, 03:53:35 pm »
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 Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

y.ivanov

• Sr. Member
• Posts: 306
Re: changing an incoming function variable when calculating an internal variable.
« Reply #7 on: September 27, 2021, 04:53:12 pm »
@Seenkao,
cccc := c * \$1010101;

Seenkao

• Sr. Member
• Posts: 261
Re: changing an incoming function variable when calculating an internal variable.
« Reply #8 on: September 27, 2021, 04:59:15 pm »
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: 306
Re: changing an incoming function variable when calculating an internal variable.
« Reply #9 on: September 27, 2021, 05:18:26 pm »
@Seenkao,
cccc := c * \$1010101;
Я выше это уже написал.
I have already written this above.
Pls, take note of the added red dollar sign.

Seenkao

• Sr. Member
• Posts: 261
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...