this procedure exchange 2 32bit values :
procedure Swap32(var A, B: TRGBQUAD);
asm
// EAX = [A]
// EDX = [B]
MOV ECX,[EAX] // ECX := [A]
XCHG ECX,[EDX] // ECX <> [B];
MOV [EAX],ECX // [A] := ECX
end;
I mean here A become B and B become A.
How can I do the same for :
procedure Swap8(var A, B: Byte);
Thanks for your help
John
> MOV ECX,[EAX] // ECX := [A]
> XCHG ECX,[EDX] // ECX <> [B];
> MOV [EAX],ECX // [A] := ECX
>How can I do the same for :
>procedure Swap8(var A, B: Byte);
Replace ecx with cl.
The instruction XCHG reg,[mem] is always automatically implementing locking protocol regardless of the presence of LOCK prefix. This
makes it very slow. It is only good for thread and process synchronization.
procedure Swap32(var A, B: LongInt); register;
asm
push [eax]
mov ecx, [edx]
pop [edx]
mov [eax], ecx
end;
> How can I do the same for :
> procedure Swap8(var A, B: Byte);
Unfortunately you cannot do exactly the same for Byte because you cannot PUSH just one byte onto the stack, but there is a better
way:
procedure SwapByte(var A, B: Byte); register;
asm
mov cl, [eax]
mov ch, [edx]
mov [edx], cl
mov [eax], ch
end;
Les.
XOR A,B
XOR B,A
XOR A,B
is probably the fastest way to swap A and B
regards Sven
> XOR A,B
> XOR B,A
> XOR A,B
>
> is probably the fastest way to swap A and B
The coolest, perhaps ;) - but not particularly relevant when the operands
are not in registers.
- Per
Sven, You beat me to it. Rgds, JohnH
Note that the original was "var A, B", i.e. you get passed pointers to
A and B. In that case, the code Les posted is much better.
--
Rudy Velthuis [TeamB] http://www.teamb.com
"The company doesn't tell me what to say, and I don't tell them
where to stick it." -- Unknown
Thanks all for your precious help !
> And it will not give wrong results as with the xor routine. If you
> call the xor routine with the same variable, ie swap32(a,a), it will
> leave you with a=0.
True.
--
Rudy Velthuis [TeamB] http://www.teamb.com
"Comedy is nothing more than tragedy deferred."
-- Pico Iyer, Time
>John Herbster wrote:
>
>>
>> "Sven Pran" wrote
>> > XOR A,B
>> > XOR B,A
>> > XOR A,B
>>
>> Sven, You beat me to it. Rgds, JohnH
>
>Note that the original was "var A, B", i.e. you get passed pointers to
>A and B. In that case, the code Les posted is much better.
>
And it will not give wrong results as with the xor routine. If you
call the xor routine with the same variable, ie swap32(a,a), it will
leave you with a=0. This can happen for example in a sort routine
where you want to swap two array elements with swap32(a[i], a[j]) and
i=j!
Therefore: Never use the xor swap technique with var parameters!
Wolfgang
--
In order to e-mail me a reply to this message, you will have
to remove PLEASE.REMOVE from the address shown in the header
or get it from http://home.netsurf.de/wolfgang.ehrhardt
(Free open source Crypto, AES, CRC, Hash for Pascal/Delphi)
procedure Swap32(var A, B: LongInt); register;
asm
mov ecx, [eax]
xor ecx, [edx]
xor [eax], ecx
xor [edx], ecx
end;
procedure TForm1.Button2Click(Sender: TObject);
var
a, b: integer;
begin
a:=$A;
b:=$B;
Swap32(a,b);
ShowMessage(Format('%x %x',[a,b]));
end;
--
regards,
Aleksandr
> Agreed. But some mod makes the XOR-code working:
>
> procedure Swap32(var A, B: LongInt); register;
> asm
> mov ecx, [eax]
> xor ecx, [edx]
> xor [eax], ecx
> xor [edx], ecx
> end;
Not if A = B, IOW, if you call it with Swap32(A, A);
--
Rudy Velthuis [TeamB] http://www.teamb.com
"Far too many development shops are run by fools who succeed
despite their many failings." -- Brion L. Webster
> Not if A = B, IOW, if you call it with Swap32(A, A);
Wrong.
In the case of Swap32(A, A):
mov ecx, [eax]
xor ecx, [edx] // ecx is now 0 as any number xor itself is 0
xor [eax], ecx // any number xor 0 remains unchanged, no problem
xor [edx], ecx // any number xor 0 remains unchanged, no problem
You can easily test it:
program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils;
procedure Swap32(var A, B: LongInt); register;
asm
mov ecx, [eax]
xor ecx, [edx]
xor [eax], ecx
xor [edx], ecx
end;
var
a, b: integer;
begin
a:=$76543210;
b:=$89ABCDEF;
WriteLn(Format('%x %x',[a,b]), ' original');
Swap32(a,a);
Swap32(b,b);
WriteLn(Format('%x %x',[a,b]), ' no change');
Swap32(a,b);
WriteLn(Format('%x %x',[a,b]), ' swapped');
Swap32(a,b);
WriteLn(Format('%x %x',[a,b]), ' swapped again');
ReadLn;
end.
--
Why not?
EAX = EDX
mov ecx, [eax] ecx = 'A'
xor ecx, [edx] ecx = 0
xor [eax], ecx [eax] unchanged
xor [edx], ecx [edx] unchanged
> Why not?
> EAX = EDX
> mov ecx, [eax] ecx = 'A'
> xor ecx, [edx] ecx = 0
> xor [eax], ecx [eax] unchanged
> xor [edx], ecx [edx] unchanged
OK, got it.
--
Rudy Velthuis [TeamB] http://www.teamb.com
"The backbone of surprise is fusing speed with secrecy."
-- Von Clausewitz (1780-1831)
procedure Swap32(var A, B: LongInt);
var
T: LongInt;
begin;
T:=A xor B;
A:=A xor T;
B:=B xor T;
end;
--
regards,
Aleksandr
Is that more efficient than:
procedure Swap32(var A, B: LongInt);
var
T: LongInt;
begin;
T:=A;
A:=B;
B:=T;
end;
Regards
Uffe
--
regards,
Aleksandr
Believeing that I was the one introducing the XOR feature in this thread let
me tell from where i knew this:
In IBM system/360 (mainframe systems) we have an operation XC which actually
performs the XOR process on strings of up to 256 bytes.
This operation is frequently used for zeroing out fields (XC A;A) and also
for swapping fields without any need for temporary storage.
If I remember correct the OP on this thread had a subroutine using register
calling conventions (default in Delphi) which means that the routine:
procedure swap32(A, B: integer);
asm
XOR EAX,EDX
XOR EDX,EAX
XOR EAX,EDX
end;
will always work correct.
regards Sven
| In IBM system/360 (mainframe systems) we have an operation XC...
Wow! You must be another "Ol'timer." <g>
--
Q
06/17/2008 10:02:45
XanaNews Version 1.17.5.7 [Q's Salutation mod]
Yes. And there was PL/I the best optimizer IMO.
--
regards,
Aleksandr
>procedure swap32(A, B: integer);
>asm
> XOR EAX,EDX
> XOR EDX,EAX
> XOR EAX,EDX
>end;
>
>will always work correct.
Yes. But it is completely useless because it only exchanges the
registers. And
xchg eax, edx
would be another code which does the same useless thing but more
effectively :)
Jfj,
Do you mean for swapping between big and little endian?
In-place or to a different destination?
Rgds, JohnH
> Yes. But it is completely useless because it only exchanges the
> registers. And
>
> xchg eax, edx
>
> would be another code which does the same useless thing but more
> effectively :)
Did you read the part of the implied LOCK on XCHG in the other messages
of this thread?
--
Rudy Velthuis [TeamB] http://www.teamb.com
"Don't be so humble - you are not that great."
-- Golda Meir (1898-1978) to a visiting diplomat
>> xchg eax, edx
> Did you read the part of the implied LOCK on XCHG in the other messages
> of this thread?
Doesn't apply to the register-only variant.
- Per
Actually, the old (V2.3.0) PL/I compiler was/is pretty bad compared to
most PC stuff, and even the new versions leave a lot to be desired in
some occasions. Worse, they produce almost unreadable assembler listings
that make it pretty hard to see what's actually going on...
Robert (Using PL/I since 1985...)
--
Robert AH Prins
robert dot ah dot prins on gmail
| Robert (Using PL/I since 1985...)
--
Q <quit using PL/1 in 1974>
06/18/2008 20:48:10
No, there is no language called PL/1.
> I think PL/I produces well readable and very optimized assembler
> listings.
About which PL/I compiler are we talking? As I wrote, the V2.3.0
assembler listings are readable (provided you use the 'lc(N)' compiler
option, with N>= 100), the assembler listing of the Enterprise PL/I
compiler, excusez-le-mot, stink, and unlike the V2.3.0 listings, there's
virtually no trace of any of the PL/I varaables to be found anymore.
As for optimisation, the V2.3.0 compiler is absolutely terrible in many
ways - I once reduced the CPU time of a program from 3 hours to 20
minutes by changing just a single statement. As this was with a former
client, I don't know how the V3R7M0 compiler would handle it. However,
the latter will generate complete crap code for a 'BY NAME' assignment,
where the destination is BASED.
Finally, the Enterprise Compiler cannot even handle all programs the
V2.3.0 compiler could compile, try this little gem (as it's likely to
wrap, I've added $$$ to the start and end of each line)
$$$%dcl z%z='put edit';proc options(main;q=''''put list(m;do
i=1,2;z(q)skip;do j=$$$
$$$1to 78c=substr(m(i),j;if c=q
z(c;z(c;end;z(q',';dcl(c,q)char,m(2)char(99)init($$$
$$$'%dcl z%z=''put edit'';proc options(main;q=''''''''put list(m;do
i=1,2;z(q)skip;do j=',$$$
$$$'1to 78c=substr(m(i),j;if c=q
z(c;z(c;end;z(q'','';dcl(c,q)char,m(2)char(99)init(',$$$
Robert
Could you, please, translate this to Delphi? Just for fun ;-)
Eriks
| No, there is no language called PL/1.
Yes there is. It's the same language as PL/I. Both acronyms have been
routinely and interchangeably used for forty years. <g> (A quick
Google will show that they still refer to the same language.)
--
Q
06/19/2008 10:07:28
Take your pick from any of these
http://www.nyx.net/~gthompso/self_pasc.txt
It's a quine, and what more, it's the smallest possible quine in PL/I
using the IBM V2.3.0 compiler (with some pretty non-standard compiler
options) The program throws a load of errors that would make any other
compiler give up, but miraculously, it also produces correctly working
code! It does not compile with the new and shiny Enterprise Compilers...
> "Robert AH Prins":
> No, there is no language called PL/1.
PL/I was developed by IBM as part of the development of OS/360.
IBM OS/360 has two PL/I compilers: PL/1 F-compiler (pgm=IEMAA) and
PL/I optimizer.
>> I think PL/I produces well readable and very optimized assembler
>> listings.
> About which PL/I compiler are we talking?
I am about second one.
> $$$%dcl z%z='put edit';proc options(main;q=''''put list(m;do
> i=1,2;z(q)skip;do j=$$$
> $$$1to 78c=substr(m(i),j;if c=q
> z(c;z(c;end;z(q',';dcl(c,q)char,m(2)char(99)init($$$
> $$$'%dcl z%z=''put edit'';proc options(main;q=''''''''put list(m;do
> i=1,2;z(q)skip;do j=',$$$
> $$$'1to 78c=substr(m(i),j;if c=q
> z(c;z(c;end;z(q'','';dcl(c,q)char,m(2)char(99)init(',$$$
I wrote my PL/I programs in Pascal style without any problem.
--
regards,
Aleksandr