flat assembler
Message board for the users of flat assembler.
![]() Goto page 1, 2, 3, 4, 5, 6, 7, 8 Next |
Author |
|
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 |
|||
![]() |
|
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.
|
|||
![]() |
|
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 ![]() Coming back to topic: "LocoDelAssembly" summarized important aspects of this huge discussion for me: ![]() Quote:
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 |
|||
![]() |
|
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). |
|||
![]() |
|
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 |
|||
![]() |
|
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. |
|||
![]() |
|
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. ![]() |
|||
![]() |
|
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.
|
|||
![]() |
|
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:
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. |
|||
![]() |
|
Raedwulf 12 Dec 2006, 13:41
Comment Comment Comment... Always does the trick
![]() xor eax, eax is obvious to most asm programmers (or coders ![]() or bl, bl surely doesn't take a genius to work out..., besides comments do help ![]() |
|||
![]() |
|
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.... 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... ![]() |
|||
![]() |
|
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).
|
|||
![]() |
|
LocoDelAssembly 12 Dec 2006, 16:39
Quote: Chapter 4 Instruction-Decoding Quote: 4.6 Short Instruction Encodings Yes Tomasz, that is what I mean. ![]() 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. |
|||
![]() |
|
bubach 12 Dec 2006, 17:31
Tom, why try to make everyone see it your way when nobody agrees with you?
![]() |
|||
![]() |
|
RedGhost 12 Dec 2006, 19:29
bubach wrote: Tom, why try to make everyone see it your way when nobody agrees with you? I suppose freedom of speech is freedom to be very opinionated ![]() _________________ redghost.ca |
|||
![]() |
|
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 ![]() _________________ All your opcodes are belong to us |
|||
![]() |
|
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?
![]() |
|||
![]() |
|
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. |
|||
![]() |
|
Plue 13 Dec 2006, 17:48
sbb > SuBtract with Borrow, do you really need a comment for that?
|
|||
![]() |
|
Goto page 1, 2, 3, 4, 5, 6, 7, 8 Next < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.