flat assembler
Message board for the users of flat assembler.

 Index > Compiler Internals > Bug? -1 and 5 gives me -1
Author
BiMode

Joined: 14 Sep 2007
Posts: 14
Location: Thailand
BiMode 14 Sep 2007, 13:39
Hi Tomasz long time no see hehe,
Now I'm back with bug report (maybe?):

Code:
```mov eax, -1 and 5
```

The expression above gives me -1 insteed of 5 (or Do I get something wrong about Fasm?).
14 Sep 2007, 13:39
LocoDelAssembly

Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 14 Sep 2007, 14:21
Code:
```a = -1 and 5
mov eax, a    ```

EAX = -1 again.

Code:
```a = 5 and -1
mov eax, a    ```

EAX = 5

Code:
```a = (-1) and 5
mov eax, a
```

EAX = 5

Code:
`mov eax, (-1) and 5    `

EAX = 5

FASM 1.64
Code:
```a = -1 and 5
mov eax, a    ```

EAX = 5

Code:
`mov eax, -1 and 5    `

EAX = 5

Seems to be a bug then
14 Sep 2007, 14:21
Tomasz Grysztar

Joined: 16 Jun 2003
Posts: 8351
Location: Kraków, Poland
Tomasz Grysztar 15 Sep 2007, 13:03
This was in fact a bug fix - according to the documentation the "-" operator has lower priority than "and", and thus "-1 and 5" should first compute AND and then compute the negation. I could also change documentation to define the different priorities for the binary and unary "-" operator (since they are a different operators really), but I chose to make it so that they both have the lowest priority. The logic behind it is that:
Code:
`mov eax,-1 and 5    `

and
Code:
`mov eax,0 - 1 and 5    `

should both give the same result (even though it's unary "-" in the first one and binary "-" in the second).
15 Sep 2007, 13:03
tom tobias

Joined: 09 Sep 2003
Posts: 1320
Location: usa
tom tobias 15 Sep 2007, 13:21
BiMode wrote:
mov eax, -1 and 5
How fortunate that I am not serving as your employer, else you would have been terminated immediately for submitting crap like this.
NEVER combine ambiguous operands in a single expression.
THERE IS NO EXCUSE for this shoddy "coding".
Learn how to create a PROGRAM instead.
Tomasz wrote:
This was in fact a bug fix ...

ABSOLUTELY WRONG.
Tomasz has here provided the FASM world with a LICENSE, not a bug fix; This license represents ENCOURAGEMENT of idiots who write garfle, and pass it off as "programming".
Nonsense!!!!
A true "bug fix", would have presented a BLACK SCREEN with RED LETTERS proclaiming the user an idiot, and recommending that they read ANY standard programming textbook.
THERE IS NO, NONE, ZERO, NADA, NULL situations in the real world, where one must combine a data movement instruction, and a Boolean operation, into a single command. If in some deluded person's mind, such a technique results in some kind of memory saving, or execution time reduction, such "benefit" is far outweighed by the amount of time lost trying to understand exactly what the "programmer", i.e. "coder" is trying to accomplish.
I defy ANYONE on this forum to offer a real world illustration in which a program WILL NOT FUNCTION unless two instructions are combined into a single new, terse, "obfuscated" instruction.
EMASCULATION TO ALL OBFUSCATORS!!
15 Sep 2007, 13:21
vid
Verbosity in development

Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid 15 Sep 2007, 13:44
tom: you prefer this way?
Code:
`mov eax, (-1) and 5    `

i believe that "unary operators have highest priority" rule is sooo much obvious that we don't need to specify this explicitly.

Also remember that this WAS NOT part of code (nor part of "program"). This was example code demonstrating FASM bug (understand: difference between what manual says and what FASM does), and best such example is the simplest possible example. Couldn't have been done better.
15 Sep 2007, 13:44
LocoDelAssembly

Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 15 Sep 2007, 16:17
I prefer the bugged version then

tom, I really don't understand you this time, this kind of construct exists for make the code clear rather than obfuscated.

Seems that you prefer
Code:
```mov eax, -1
and eax, 5    ```
But here is not a matter of optimization but you are obfuscating the fact that it is a constant.

Suppose that a given hardware mapped at a memory address EBX needs the first bit clear and you need to store a constant k on it. What would you do? This?
Code:
```mov eax, k ; k is an assembly time variable, not a memory address
and eax, -2
mov [ebx], eax    ```

Suppose that k is known and you don't want parametrization, then you would do this?
Code:
```mov eax, 9
and eax, -2
mov [ebx], eax    ```

Maybe this?
Code:
`mov dword [ebx], 8    `

I think that performing the AND operation brings clarity, not obfuscation because it is documenting the value constraints while implementing it with pure assembly makes no clear that if you are intentionally adding delays required for the hardware, or if you are modifying the EFLAGS for code that will be executed later, etc.

If you want more clarity perhaps using this
Code:
```datum = (-2) and k
mov dword [ebx], datum    ```
But definetivelly it must be done this way (IMHO of course).

Sorry if something about what I said is product of misreading you but believe that I thought you would consider this a good practise rather than obfuscation.
15 Sep 2007, 16:17
tom tobias

Joined: 09 Sep 2003
Posts: 1320
Location: usa
tom tobias 16 Sep 2007, 12:49
vid wrote:

mov eax, (-1) and 5

i believe that "unary operators have highest priority" rule is sooo much obvious that we don't need to specify this explicitly.

Also remember that this WAS NOT part of code (nor part of "program"). This was example code demonstrating FASM bug (understand: difference between what manual says and what FASM does), and best such example is the simplest possible example. Couldn't have been done better.

Yes, vid, you are correct, BiMode's example was very suitable to demonstrate this disparity, and, again, not to beat a dead horse, my point was that the problem, instead, is that FASM encourages such practices, when from my perspective, it more properly ought to signal that two operations are carried out within a single instruction, and therefore the code ought not assemble.
It is not, in other words, to be completely unambiguous, NOT THE absence of parentheses, to which I object, but the performance of two ( or three, or n quantity of operations) within a single instruction.
LocoDelAssembly wrote:
...
this kind of construct exists for make the code clear rather than obfuscated.

Seems that you prefer

mov eax, -1
and eax, 5

Absolutely. Of course, one could just write in Hexadecimal, instead of using roman letters. For some, that would be even easier. Then, one could have the whole program as a sequence of hex symbols, without any kind of punctuation, comments, or explanations.

LocoDelAssembly wrote:

But here is not a matter of optimization but you are obfuscating the fact that it is a constant.

Gosh, loco, I don't know what to write. First I guess, one wonders, what "IT" refers to above, in your sentence. I presume, maybe incorrectly, that you are referring to "5". What else can it be? To me, the operand, five, is not a variable, it is a specific value, five, unchangeable no matter how many times one executes this code, therefore, by definition, it IS a constant. Secondly, I guess I have to disagree with you that writing "and eax,5" is obtuse, arcane, bewildering, or represents an unintentional attempt to obfuscate. The constant "five", seems to me, very clear, unequivocal, and completely understandable. Maybe there is simply something wrong with my visual system, that I find it disagreeable to morph two instructions into one. More likely, the fault rests with my Frontal lobes, rather than my visual system per se, because I prefer everything VERY SIMPLE, VERY ELEMENTARY, VERY transparent, so much so, that folks who are genuinely proficient, are irritated by the necessity to write TWO instructions, when one suffices. This is exactly the same as chess: some people are sufficiently talented that they can imagine 8 or ten or twelve moves ahead, while I struggle to see one or two moves beyond the current board situation. Once a guy suggested my resignation, after I made a colossal error, and I looked at him in disbelief: "But I just captured your Bishop", yes, he replied, and you are going to lose your king, as a result, in just four more moves. I had wandered into a classic, documented trap, dating from the 18th century.
I dislike the solutions offered to calculus problems when the instructor glosses over all the intermediate steps, and jumps straight to the arithmetic at the end. I want EACH step defined, and elaborated, in stultifying boredom for those truly proficient. Same for Organic Chemistry. I cannot abide those who gloss over those intermediate reactions, and jump straight to the end products, as though the reactions were obvious. I am just not sufficiently bright to follow the logic without seeing it in front of me, step by step, an approach very painful for those with talent.
I dislike the approach of those who read the first sentence of a novel, and then jump to the last paragraph, and close the book satisfied. If I will read Tolstoy, it will be a week long project, requiring many hours each day, as I struggle to envision the clouds in the sky, and the wind blowing the girl's hair--well, once I did have hair too!!!
16 Sep 2007, 12:49
vid
Verbosity in development

Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid 16 Sep 2007, 13:00
which one is more readable to you?
Code:
```and eax, 0xFFBFFFFF
and eax, not (1 shl 22)
```

I really really hope it is the second one, even though instruction operand contains two assembly-time operations. At least for everyone else, the second form is much more apparent than first. By NOT providing such feature would FASM force (not encourage) unreadable code (program, whatever), like first instruction is.
16 Sep 2007, 13:00
tom tobias

Joined: 09 Sep 2003
Posts: 1320
Location: usa
tom tobias 16 Sep 2007, 13:16
vid wrote:
which one is more readable to you?
Code:
```and eax, 0xFFBFFFFF
and eax, not (1 shl 22)
```

The first is obviously more readable, but inscrutable. Why use that particular value? Why create the constant with such labor? Why not simply define the constant first, give it a name, and use it in the program? For example:
0 zero, rather than 0xABC - 0xABC

vid wrote:

I really really hope it is the second one, even though instruction operand contains two assembly-time operations. At least for everyone else, the second form is much more apparent than first....
Umm, well, no, vid, the second choice contains three, not two instructions. As regards, "everyone else", I am unimpressed by the vast quantity of people who do things incorrectly.
16 Sep 2007, 13:16
vid
Verbosity in development

Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid 16 Sep 2007, 13:29
purpose of those instruction is to clear bit 22 of course. It could as well be done this way:
Code:
```SPECIAL_BIT_ANDMASK = not (1 shl 22)
```

It doesn't matter, you still have to type the FFBFFFFF value somehow.

Whether the value is assigned to numeric constant or used directly doesn't matter. Problem is about how to write readable value which has all bits sets, except bit 22. I find "not (1 shl 22)" much more readable than "0xFFBFFFFF".

Small test to try it yourself:
- which bit is cleared by "and rax, 0xFFFFFFF8FFFFFFFF"
- which bit is cleared by "and rax, not (1 shl 35)"

which one took you longer?

Quote:
Umm, well, no, vid, the second choice contains three, not two instructions.

No, it contains one instruction, and two compile-time bitwise operators. It is just different (more readable) syntax for same instruction.
16 Sep 2007, 13:29
BiMode

Joined: 14 Sep 2007
Posts: 14
Location: Thailand
BiMode 16 Sep 2007, 13:37
Tomasz Grysztar wrote:
This was in fact a bug fix - according to the documentation the "-" operator has lower priority than "and", and thus "-1 and 5" should first compute AND and then compute the negation. I could also change documentation to define the different priorities for the binary and unary "-" operator (since they are a different operators really), but I chose to make it so that they both have the lowest priority. The logic behind it is that:
Code:
`mov eax,-1 and 5    `

and
Code:
`mov eax,0 - 1 and 5    `

should both give the same result (even though it's unary "-" in the first one and binary "-" in the second).

Ok, I got it! I have to understand the operator priorities first...
16 Sep 2007, 13:37
LocoDelAssembly

Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 16 Sep 2007, 15:54
tom tobias wrote:

Gosh, loco, I don't know what to write. First I guess, one wonders, what "IT" refers to above, in your sentence. I presume, maybe incorrectly, that you are referring to "5". What else can it be?

Sorry for my above normal weak English. And no, I mean that the constant is "mask AND k" (where mask=-1 and k=5 in this example), but if I break it into two CPU instructions instead of using assembler operations then I'm using two constants instead of one.

Anyway, by the discussion followed between you and vid seems that you don't prefer to break into CPU instructions but using a hardcoded, non parametrizable constant value then. I wonder how is possible that you consider a plain hex value more clear than a couple of self descripting operations that also gives the changes to adjust the value without worrying getting out of constraints.
16 Sep 2007, 15:54
Hayden

Joined: 06 Oct 2005
Posts: 132
Hayden 16 Sep 2007, 16:34
seems to be an annoying bug for some... lol

_________________
New User.. Hayden McKay.
16 Sep 2007, 16:34
f0dder

Joined: 19 Feb 2004
Posts: 3175
Location: Denmark
f0dder 16 Sep 2007, 17:04
I wonder how many people think like Tom on this issue... hopefully, not many.
16 Sep 2007, 17:04
Octavio

Joined: 21 Jun 2003
Posts: 366
Location: Spain
Octavio 16 Sep 2007, 22:49
f0dder wrote:
I wonder how many people think like Tom on this issue... hopefully, not many.

I think like Vid (only on this subject) in most common languages
sign change has more priority than substraction, or unary operators have more priority than binary operators.
16 Sep 2007, 22:49
 Display posts from previous: All Posts1 Day7 Days2 Weeks1 Month3 Months6 Months1 Year Oldest FirstNewest First

 Jump to: Select a forum Official----------------AssemblyPeripheria General----------------MainTutorials and ExamplesDOSWindowsLinuxUnixMenuetOS Specific----------------MacroinstructionsOS ConstructionIDE DevelopmentProjects and IdeasNon-x86 architecturesHigh Level LanguagesProgramming Language DesignCompiler Internals Other----------------FeedbackHeapTest Area

Forum Rules:
 You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot vote in polls in this forumYou cannot attach files in this forumYou can download files in this forum