News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Rant: NOT

Started by Ian_B, July 14, 2006, 10:25:33 AM

Previous topic - Next topic

Ian_B

<RANT>
Why did Intel have to create such a useful opcode - NOT - then destroy half the usefulness by not making it update the flags? What twisted reason was there for this when all other logic/math functions do, like NEG and shifts/rotates? Having to work around it when doing a NOT followed by a JZ/JNZ would have been SO simple is really making me irritable...  :tdown
</RANT>

Ian_B

drizz

XOR [r/m], -1  :wink
The truth cannot be learned ... it can only be recognized.

dsouza123

#2
Various alternatives.


.data
   szC    db "NOT operation",0
   szfmtI db "NOT : %lu",13,10
          db "XOR : %lu",13,10
          db "SUB : %lu",13,10
          db "NEG : %lu",13,10
          db "AND : %lu",0

   szM    db "The Alternatives",13,10
   szZ    db 256 dup (0)

.data?
   z0  dd  ?
   z1  dd  ?
   z2  dd  ?
   z3  dd  ?
   z4  dd  ?

.code
   mov z0, 0
   mov z1, 0
   mov z2, 0
   mov z3, 0
   mov z4, 0


   not z0        ; --- equivalent functions, various flags modified (or not)

   xor z1, -1    ; ---

   mov eax, -1   ; ---
   sub eax, z2
   mov z2, eax

   neg z3        ; ---
   sub z3, 1

   not z4        ; ---
   and z4, -1

   invoke wsprintf,ADDR szZ,ADDR szfmtI,z0,z1,z2,z3,z4
   invoke MessageBox, NULL, addr szM, addr szC, MB_OK

Wistrik

Maybe they had a Wayne's World attack while coding the instruction...

"Let's make this instruction set flags too, NOT!!!"

I'm sure they had their reasons, but we may never know what they were.

Casper

Let's see, instructions that do not set flags...

8086
CALL, CBW, CWD, ESC, HLT, IN, INTO, Jxx, LAHF, LDS, LEA, LES, LOCK, LODSB, LODSW, LOOPxx, MOV, MOVSB, MOVSW, NOP, NOT, OUT, POP, PUSH, PUSHF, REPxx, RET, STOSB, STOSW, WAIT, XCHG, XLAT,
286
BOUND, CLTS, ENTER, INS, INSB, INSW, LEAVE, LGDT, LIDT, LLDT, LMSW, LTR, OUTS, OUTSB, OUTSW, POPA, PUSHA, SGDT, SIDT, SLDT, SMSW, STR,
386
CDQ, CWDE, IN, INS, INSD, JECXZ, LEA, LFS, LGS, LODSD, LSS, MOV, MOVSD, MOVSX, MOVZX, NOT, OUT, OUTSD, POP, POPAD, PUSH, PUSHAD, PUSHFD, REP, REPE, REPNE, REPNZ, REPZ, SETxx, STOSD, XCHG

So NOT is not as unique as you seem to think.
Paul

Ian_B

#5
Quote from: Casper on July 14, 2006, 11:44:27 PMSo NOT is not as unique as you seem to think.
Paul

Great list, thanks. But look at which instructions you've listed. Apart from CDQ, which alters two registers so the meaning of any flags set could be dubious, and LEA, all the others are movement operations - all the MOV and PUSH variants and control flow operations like CALL/LEAVE/Jxx. NOT is an arithmetic/logic operator, and the only one in that list. I find the inconsistency astonishing. And it caused no end of bugs in my code until I realised that it wasn't setting flags as seemed natural and logical.

As a single-op (no argument) alternative, I've been playing with NEG, but having a -1 around as a register value is marginally more useful than a 1... and the NEG often leaves the register in the wrong state for me. I guess the XOR -1 drizz/dsouza suggested, especially if you already have a -1 handy in a register, is the best alternative.

Ian_B

Casper

NOT is not really an arithmetic instruction per se as it doesn't have a different source/destination strategy.  Flags are set when the result is determenant.  In this case the result is always known, why you would expect a flag to be set is beyond me.  ZF for example would only be set in one instance and the value is known whereas with arithmetic operations, ZF could be set with any operation so setting it is mandatory.  I do not wish to bash your coding methods but you are leaving yourself open, here...

Paul

Ian_B

#7
Not so much bad coding methods... more practice I've been following that has served well up till now. Where I have functions that either fail or complete OK, I have returned 0 or true. In my VB heritage, true is -1, and this is a useful value to return as I have said. Many API functions return -1, especially the file operation ones, often INVALID_HANDLE_VALUE or INVALID_FILE_POINTER, rather than a generic C true (any non-zero value) so you have a situation where often the return from a function is 0 or -1, and therefore a NOT to test the return value while also creating a useful register value in the process on a false return in the same op is a handy way of compressing code.

I guess I could rewrite ALL my file functions to return 1 instead of -1 for true, and start using NEG to test my return values...  :(   but this shouldn't have been necessary if they'd not made this bizarre choice of flag-setting logic. I realise it's just my problem...  ::)

Ian_B

Casper

I am sympathetic to your plight.  I have been coding in assembly as my profession all of my life it seems and this problem you have detected is only one of many.  There have been many instances where even the assembler has broken down if served very complex code.  I, also, have had to learn to live with the tools presented to me because I was always too busy making money to try to make a better product.  I have not designed an assembler in years and now I find myself too old and too ill to do so again.  Good fortune to you Ian.

Paul

drizz

there are numerous ways to test -1 not just <not>

call fun
test eax,eax
js bad
---
inc eax
jz bad
---

or to test 1 (true)

dec eax
jnz bad

or to check for both 0 and -1

dec eax
js bad





The truth cannot be learned ... it can only be recognized.