flat assembler
Message board for the users of flat assembler.

Index > Main > XOR EAX,EAX

Goto page 1, 2, 3, 4, 5, 6, 7, 8  Next
Author
Thread Post new topic Reply to topic
DOS386



Joined: 08 Dec 2006
Posts: 1905
DOS386 12 Dec 2006, 00:17
I frequently see "nonsense" instructions having 2 identical operands
generating always ZERO (?) or having NO (?) effect like:


XOR EAX,EAX

or

OR BL,BL


What is the sense of them ? Intentionally zeroizing the register ?

MOV EAX,0

would not work - or is slower or more memory hoggy ? Shocked

Test whether BL = 0 ?

CMP BL,0

is impossible or also bad ? Shocked

Are there other usages of such "calculations" ?

_________________
Bug Nr.: 12345

Title: Hello World program compiles to 100 KB !!!

Status: Closed: NOT a Bug
Post 12 Dec 2006, 00:17
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 12 Dec 2006, 00:49
xor eax, eax => 2 bytes
mov eax, 0 => 5 bytes (but not modify the flags in case you need to preserve them)

ORing against itself can be used to test if operand is zero or negative for example. There are just well known ways to perform such actions.

Here a big discusion about this http://board.flatassembler.net/topic.php?t=4485
Post 12 Dec 2006, 00:49
View user's profile Send private message Reply with quote
RedGhost



Joined: 18 May 2005
Posts: 443
Location: BC, Canada
RedGhost 12 Dec 2006, 01:03
please search the forum or read the documentation before posting these questions, there are multiple topics on this subject.
Post 12 Dec 2006, 01:03
View user's profile Send private message AIM Address MSN Messenger Reply with quote
DOS386



Joined: 08 Dec 2006
Posts: 1905
DOS386 12 Dec 2006, 01:59
Quote:
search the forum or read the documentation


Sorry ... but this issue is NOT easy to search (unlike "CPUID" for ex.).
Unsurprisingly, an issue similar to mine has already been discussed
(many months and pages back). I am not the first one asking about
this ... and probably will not remain the last one Confused

Coming back to topic:

"LocoDelAssembly" summarized important aspects of this huge discussion for me: Smile

Quote:

xor eax, eax => 2 bytes
mov eax, 0 => 5 bytes (but not modify the flags in case you need to preserve them)

ORing against itself can be used to test if operand is zero or negative for example. There are just well known ways to perform such actions.


Thanks.

XOR EAX,EAX saves memory.

Does the same apply to OR'ing ?

What I am interested by now is what other instructions can expose such
syntax and why it is being done (zeroizing register, memory save). Marginal
speed issues are not relevant for me by now.

_________________
Bug Nr.: 12345

Title: Hello World program compiles to 100 KB !!!

Status: Closed: NOT a Bug
Post 12 Dec 2006, 01:59
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 12 Dec 2006, 02:09
Sometimes size, sometimes speed (look at the posts of revolution in the link I posted). In the case of OR BL, BL Vs CMP BL, 0
OR BL, BL => 2 bytes
CMP BL, 0 => 3 bytes

When you want to compare instructions encoding sizes against each other you can use FASMW, write the instruction and press Ctrl+F9, then remove it and put the other instruction and press Ctrl+F9 again and compare the sizes. (note that fasm defaults to 16-bit mode code, if you code is intended to be executed in 32-bit mode then begin the source with "use32" and in the following line write the instruction).
Post 12 Dec 2006, 02:09
View user's profile Send private message Reply with quote
WytRaven



Joined: 08 Sep 2004
Posts: 45
Location: Canberra, Australia
WytRaven 12 Dec 2006, 02:39
Here is my standard Win32 Message Pump it illustrates where self or-ing can be useful:

Code:
MessagePump: ; Main application window message pump
        xor     eax, eax                        ; Zero EAX
        invoke  GetMessage, g_Message,\         ; lpMsg
                            eax,\               ; hWnd - 0 means get all messages for windows in this thread
                            eax,\               ; wMsgFilterMin - if both this and wMsgFilterMax are 0 don't filter at all
                            eax                 ; wMsgFilterMax - if both this and wMsgFilterMin are 0 don't filter at all
        or      eax, eax                        ; Oring EAX with itself will produce either 0 in EAX and set the Z flag if
                                                ; EAX was already 0 or no change in EAX and will clear the Z flag
        jz      ExitApplication                 ; If EAX is 0 after Oring then we have recieved a WM_QUIT message and Z
                                                ; flag will be set so exit
        invoke  TranslateMessage, g_Message     ; lpMsg
        invoke  DispatchMessage,  g_Message     ; lpMsg
        jmp     MessagePump                     ; Didn't get a WM_QUIT message obviously so jump back for another loop

ExitApplication:
        invoke  ExitProcess, 0                  ; Tell Windows that we want to die and return 0 in the process    

_________________
All your opcodes are belong to us
Post 12 Dec 2006, 02:39
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8367
Location: Kraków, Poland
Tomasz Grysztar 12 Dec 2006, 06:44
NTOSKRNL_VXE wrote:
Sorry ... but this issue is NOT easy to search (unlike "CPUID" for ex.).

You should have started searching from this thread: http://board.flatassembler.net/topic.php?t=4816 (always on the top of "Main" forum). The good old dispute about "xor reg,reg" is listed there as a first link in "Optimization" section.
Post 12 Dec 2006, 06:44
View user's profile Send private message Visit poster's website Reply with quote
tom tobias



Joined: 09 Sep 2003
Posts: 1320
Location: usa
tom tobias 12 Dec 2006, 10:47
two points:
1. search engine:
A. entering "xor eax,eax", with or without the quotes, yields this thread as first choice, I did not observe the longwinded diatribes of yesteryear anywhere in the output;
B. entering "mov eax,0", with or without the quotation marks, also ignores the long chants (or some would argue, rants, of bygone days).
C. entering "coding versus programming" also fails to bring up the main threads of former, more passionate, times of glory.
2. THEREFORE:
in summary, to answer your question, NTOSKRNL-VXE, yes, mov eax,0 is the preferred choice among programmers, while xor eax,ecx (oops, just performed an unintentional, and unrecognizeable, boolean operation, as a consequence of a simple typographical mistake, sorry,...) is the choice of 99.99% of FASM forumers. As far as I know, I am the odd man out, the only one on this forum, who will NEVER use a boolean function to clear or test a register. Yes, programming for me is a kind of religious attitude...
"OR, something", as WytRaven so brilliantly demonstrated, (instead of the correct, "CMP, something",) ONLY LEADS TO CONFUSION, when twenty people are working on the same project. Sure, as LocoDelAssembly explained, ONE CAN SAVE precious bytes, HURRAH!!! and, this is EXTREMELY IMPORTANT, because that way, by saving those precious bytes, we have 400 million bytes unused, instead of only 398 million bytes unused, had we employed the more obvious, less error-prone, and more readable, MOV or CMP instructions. Finally, let us not forget the importance of saving TIME, by having an execution requiring a mere 37.1 nanoseconds, instead of 48.6 nanoseconds. Hey, those nanoseconds add up. We are not talking about just a few picoseconds here. This is a GENUINE time savings using XOR, instead of MOV, and OR instead of CMP.
And, finally, as SO MANY ARDENT FASM FORUM members have noted, REAL assembly language programmers, ENJOY writing obscurely. They derive SATISFACTION from creating a tangled mess of CODE, that only THEY can decipher (--LOOK AT FASM ITSELF), instead of a readable PROGRAM. Many of them, even imagine that WRITING CODE is an intrinsic feature, i.e. a desirable attribute, of assembly language CODING (not programming,) in order to assure inscrutable results. Fortunately, the late, Dr. Dandamudi has proved them WRONG. Your initial post is correct, MOV, and CMP are the proper instructions to use, not XOR, and OR, which MUST be reserved exclusively for Boolean arithmetic functions, if one hopes to create a readable program, instead of generating spaghetti code.
Smile
Post 12 Dec 2006, 10:47
View user's profile Send private message Reply with quote
smiddy



Joined: 31 Oct 2004
Posts: 557
smiddy 12 Dec 2006, 12:11
Don't allow Tom's prose to pursuade you one way or the other. I say be pragmatic in your approach. If your application, like say, oh, a boot sector requires precious bytes, then you will use a way to remove bytes, if your program requires readability for any number of reason, use the less confusing more direct approach that makes sense (though an assembly programer might argue differently). If your program requires precioous timing, then you'll write your program to be fast even with obscure writing in order to get the job done faster.
Post 12 Dec 2006, 12:11
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 12 Dec 2006, 13:37
tom, note that those precious bytes that you can save with shorter instructions allows the CPU to get more instructions inside its 16 bytes packets. If you use too much larger instructions then you lower the processing capabilities of the processor.

Quote:

I am the odd man out, the only one on this forum, who will NEVER use a boolean function to clear or test a register


Well if you need to clear a register then your best friend should be "AND reg, 0" since it clearly demostrates that you are clearing the register while with "MOV reg, 0" you are assigning 0 to it.
Post 12 Dec 2006, 13:37
View user's profile Send private message Reply with quote
Raedwulf



Joined: 13 Jul 2005
Posts: 375
Location: United Kingdom
Raedwulf 12 Dec 2006, 13:41
Comment Comment Comment... Always does the trick Wink

xor eax, eax
is obvious to most asm programmers (or coders Very Happy) (well should be), i don't see why there is any problem with using that and with the saving of 3 bytes....

or bl, bl
surely doesn't take a genius to work out..., besides comments do help Razz.
Post 12 Dec 2006, 13:41
View user's profile Send private message MSN Messenger Reply with quote
tom tobias



Joined: 09 Sep 2003
Posts: 1320
Location: usa
tom tobias 12 Dec 2006, 15:50
Zero has always been the most fascinating of all integers. It was only recently invented, (less than two thousand years ago, a microsecond in human evolutionary terms,) well after the discovery of other numbers. So far as I am aware, it is one of many arithmetic discoveries from the Indian subcontinent, though perhaps this is not correct, and it comes in fact from Persia. I am not sure. Nevertheless, upon "clearing" a register, all silicon is at a state of no measureable voltage, (electrical ground, or neutral), and we define that, arbitrarily, and maybe not correctly, as assigning to the register, the integer value of ZERO.
LocoDelAssembly wrote:
..."AND reg, 0" since it clearly demonstrates that you are clearing the register while with "MOV reg, 0" you are assigning 0 to it...

The difference is this: AND is a Boolean operator, which also happens to clear the register, under certain test conditions. MOV is absolute, not relative, like AND. For readability, as well as FOR SIMPLICITY (oh, there's a word the FASM forumers despise!) stick with MOV. For those who prefer OBSCURITY, ok, fine, be obtuse. Comments, cher Raedwulf, ought to explain WHAT the code is doing, not HOW to decipher the code into readable text. In other words, the comments ought to explain WHY we are testing the value of the register, (i.e. the value of the flag), not simply informing us of the fact that we are ACTUALLY ONLY testing a Register's value, rather than performing a Boolean operation on the Register, counterintuitively, since both the name and the function of the instruction, suggest the latter. Again, this is a question, first and foremost of whether or not one is writing CODE for one's own interest, one's own project, or one is participating in a GROUP effort. If for oneself, fine, write anything, no problem. But, if one hopes to have a GROUP understand this task, it better be written in the EASIEST POSSIBLE manner. The single most important aspect of attaining success on any GROUP project, is readability. For assembly language programming, please do not waste your time, trying to save memory or decrease execution time (especially NOT in a boot loader, Smiddy!!!). Make your PROGRAM as user friendly as possible, by emphasizing the EXTRA instructions, which make it possible for someone other than yourself to understand what you are trying to accomplish. The obsolete 512 byte limit is just that. OBSOLETE. Forget it. Readability is the MOST important feature in today's world, with the international community obliged to use English. Give folks all the help you can, by making your code as simple to understand as possible.
LocoDelAssembly wrote:
...allows the CPU to get more instructions inside its 16 bytes packets....
Correct me, if I am in error, Smiddy, the memory controller reads in, each clock cycle, 128 bits of data,
http://www-128.ibm.com/developerworks/library/pa-tuncpc/
the memory doesn't care if it is sixteen 8 bit ASCII characters, or 128 bits of I/O from the environment. I am unaware of any "packets" here....Decoding the 128 bits, assigning some to data, some to instructions, is certainly complex, BUT I DOUBT that it is more or less efficient to decode a MOV versus XOR. As far as I am aware, both instructions can be decoded from the 128 bit chunk of memory, in the same amount of time. Let's suppose I am WRONG. Then what? I don't care. I certainly will not change my thinking about the critical importance of writing PROGRAMS instead of CODE, just because the MOV instruction requires 489 more nanoseconds to decode than XOR.
smiddy wrote:
...be pragmatic in your approach...
Hmm. NOPE, don't agree at all, but then, I dislike the "pragmatic" solution to world environmental, economic, and political problems, too. I believe there is a correct way to do things, and an incorrect way. As far as I am concerned, deliberately misusing an instruction, just because of convention, or laziness, is not proper conduct.
Smile
Post 12 Dec 2006, 15:50
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8367
Location: Kraków, Poland
Tomasz Grysztar 12 Dec 2006, 16:03
I'm pretty sure that LocoDelAssembly did mean that "clear the register" may be understood to be a different operation from "take the 0 value and put it into that register". Unfortunately there's no a separate instruction dedicated solely to clearing the bits in registers (the only such instructions are the ones for clearing the flag bits, like CLD).
Post 12 Dec 2006, 16:03
View user's profile Send private message Visit poster's website Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 12 Dec 2006, 16:39
Quote:
Chapter 4 Instruction-Decoding
Optimizations
The optimizations in this chapter are designed to help maximize the number of instructions that the
processor can decode at one time.
The instruction fetcher of both the AMD Athlon™ 64 and AMD Opteron™ processors reads 16-byte
packets from the L1 instruction cache. These packets are 16-byte aligned. The instruction bytes are
then merged into a 32-byte pick window. On each cycle, the in-order front-end engine selects up to
three AMD64 instructions for decode from the pick window.
This chapter covers the following topics:
Topic Page
DirectPath Instructions 72
Load-Execute Instructions 73
Load-Execute Integer Instructions 73
Load-Execute Floating-Point Instructions with Floating-Point Operands 74
Load-Execute Floating-Point Instructions with Integer Operands 74
Branch Targets in Program Hot Spots 76
32/64-Bit vs. 16-Bit Forms of the LEA Instruction 77
Short Instruction Encodings 80
Partial-Register Reads and Writes 81
Using LEAVE for Function Epilogues 83
Alternatives to SHLD Instruction 85
8-Bit Sign-Extended Immediate Values 87
8-Bit Sign-Extended Displacements 88
Code Padding with Operand-Size Override and NOP 89

Quote:
4.6 Short Instruction Encodings
Optimization
Use instruction forms with shorter encodings rather than those with longer encodings. For example,
use 8-bit displacements instead of 32-bit displacements, and use the single-byte form of simple
integer instructions instead of the 2-byte opcode-ModRM form.
Application
This optimization applies to:
• 32-bit software
• 64-bit software
Rationale
Using shorter instructions increases the number of instructions that can fit into the L1 instruction
cache and increases the average decode rate.
Example
Avoid the use of instructions with longer encodings, such as those shown here:
81 C0 78 56 34 12 add eax, 12345678h ; 2-byte opcode form (with ModRM)
81 C3 FB FF FF FF add ebx, -5 ; 32-bit immediate value
0F 84 05 00 00 00 jz label1 ; 2-byte opcode, 32-bit immediate value
Instead, choose instructions with shorter encodings, like these:
05 78 56 34 12 add eax, 12345678h ; 1-byte opcode form
83 C3 FB add ebx, -5 ; 8-bit sign-extended immediate value
74 05 jz label1 ; 1-byte opcode, 8-bit immediate value


Yes Tomasz, that is what I mean.Smile

I also want to point out that we program for the microarchitecture too, so if xor eax, eax is the most appropiate for the current instruction sequence then we MUST use it. I agree that things like "eax &= 0" is stupid because it is a HLL language an it is compiler's job to use the appropiate instruction for the target microarchitecture.
Post 12 Dec 2006, 16:39
View user's profile Send private message Reply with quote
bubach



Joined: 17 Sep 2004
Posts: 341
Location: Trollhättan, Sweden
bubach 12 Dec 2006, 17:31
Tom, why try to make everyone see it your way when nobody agrees with you? Smile
Post 12 Dec 2006, 17:31
View user's profile Send private message Reply with quote
RedGhost



Joined: 18 May 2005
Posts: 443
Location: BC, Canada
RedGhost 12 Dec 2006, 19:29
bubach wrote:
Tom, why try to make everyone see it your way when nobody agrees with you? Smile

I suppose freedom of speech is freedom to be very opinionated Very Happy. I kid.

_________________
redghost.ca
Post 12 Dec 2006, 19:29
View user's profile Send private message AIM Address MSN Messenger Reply with quote
WytRaven



Joined: 08 Sep 2004
Posts: 45
Location: Canberra, Australia
WytRaven 13 Dec 2006, 02:03
I understand where Tom is coming from but I don't agree with his solution. Using a low level language to try and write readable code is counter productive. Your comments on this subject till this point tom, have all been arguments that readability in code is infinitely more important than either speed or size in code which begs the question "Why are you interested in assembly at all?". If you want readable code then use a high level language.

I think I manage to achieve a balance between both worlds by using a combination of evil (according to tom) code and very clear comments. I don't write readable code, I write readable comments instead. That snippet above did not have the comments added for the purpose of the post, those comments are copied verbatim from my code. I comment every single line of my assembly code as a rule. So when I come back to a project after a few months and have no idea what i was trying to achieve with some weird looking boolean manipulation I need only look at my comments for clarification and justification.

I can see tom's come back already..."over commenting is inefficent use of time and time is money etc..." again I would say if you want rapid development don't use assembly.

After having read the original tom-goes-on-a-rant thread some time ago I can't help but think that tom is feeling a little bored and neglected and is desperately trying to relive his glory days Wink

_________________
All your opcodes are belong to us
Post 13 Dec 2006, 02:03
View user's profile Send private message Reply with quote
smiddy



Joined: 31 Oct 2004
Posts: 557
smiddy 13 Dec 2006, 03:14
Tom, I wish I had proper time to write now, but I have a 3 year old in need of attention, he's sick. Look up differential circuits and electrical bounce. Also, I suspect with your comment you hate Einstien too? Wink I'll write in the morning, if I have time...
Post 13 Dec 2006, 03:14
View user's profile Send private message Reply with quote
pelaillo
Missing in inaction


Joined: 19 Jun 2003
Posts: 878
Location: Colombia
pelaillo 13 Dec 2006, 13:58
This is a fruitless discussion, but maybe I'm wrong and this time we could put an end to it.

To summarize, our stance is that we are talking about mnemonic opcodes that in some cases happens to be called the same way of boolean operators and that's the idea of a mnemonic, to help us remeber what a certain circuitry is going to do. If the opcode does the work without side effects, why we shouldn't use them?

How are you going to write readable programs when you use one of the following mnemonics (to cite only a few):
sbb xlatb cwde fldlg2 cmpneqps pmuludq pfcmpge stmxcsr

The answer is (as everyone is pointing out): writting proper comments and meaningful labels.
Post 13 Dec 2006, 13:58
View user's profile Send private message Yahoo Messenger Reply with quote
Plue



Joined: 15 Dec 2005
Posts: 151
Plue 13 Dec 2006, 17:48
sbb > SuBtract with Borrow, do you really need a comment for that?
Post 13 Dec 2006, 17:48
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page 1, 2, 3, 4, 5, 6, 7, 8  Next

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.