flat assembler
Message board for the users of flat assembler.

Index > Main > invert ZF

Goto page 1, 2  Next
Author
Thread Post new topic Reply to topic
Teehee



Joined: 05 Aug 2009
Posts: 570
Location: Brazil
Teehee 24 Sep 2011, 18:51
i have a function that return ZF = 0 if true.
i need to invert this value, ie, if ZF = 0 ? ZF = 1 : ZF = 0.
there is a instruction to do that?

_________________
Sorry if bad english.
Post 24 Sep 2011, 18:51
View user's profile Send private message Reply with quote
Overflowz



Joined: 03 Sep 2010
Posts: 1046
Overflowz 24 Sep 2011, 20:04
you can do something like this:
Code:
mov al,1
test al,al ;ZF = 0    

or set to 1.
Code:
xor al,al ;ZF = 1    

or maybe you want to try JZ/JNZ instructions ?
Post 24 Sep 2011, 20:04
View user's profile Send private message Reply with quote
Teehee



Joined: 05 Aug 2009
Posts: 570
Location: Brazil
Teehee 24 Sep 2011, 20:14
i was looking for an only instruction to do that Sad


Last edited by Teehee on 24 Sep 2011, 20:15; edited 1 time in total
Post 24 Sep 2011, 20:14
View user's profile Send private message Reply with quote
Overflowz



Joined: 03 Sep 2010
Posts: 1046
Overflowz 24 Sep 2011, 20:15
I haven't seen such thing yet. I saw how to modify flags with PUSHFD and then OR-ing it. I think there's no such way Laughing
Post 24 Sep 2011, 20:15
View user's profile Send private message Reply with quote
MHajduk



Joined: 30 Mar 2006
Posts: 6115
Location: Poland
MHajduk 24 Sep 2011, 20:31
What about this couple of instructions:
Code:
lahf
btc       eax, 14
sahf    
They invert ZF as needed (but destroy the previous value of AH, of course).
Post 24 Sep 2011, 20:31
View user's profile Send private message Visit poster's website Reply with quote
Teehee



Joined: 05 Aug 2009
Posts: 570
Location: Brazil
Teehee 24 Sep 2011, 20:52
MHajduk wrote:
What about this couple of instructions:
Code:
lahf
btc   eax, 14
sahf    
They invert ZF as needed (but destroy the previous value of AH, of course).


i can do that with 2 instructions:

Code:
setz al
test al,al    

i just wanted do that with 1 Razz
Post 24 Sep 2011, 20:52
View user's profile Send private message Reply with quote
MHajduk



Joined: 30 Mar 2006
Posts: 6115
Location: Poland
MHajduk 24 Sep 2011, 20:53
Another possibility:
Code:
setnz        al
xor       al, 1    
Wink
Post 24 Sep 2011, 20:53
View user's profile Send private message Visit poster's website Reply with quote
MHajduk



Joined: 30 Mar 2006
Posts: 6115
Location: Poland
MHajduk 24 Sep 2011, 21:10
Teehee wrote:
i have a function that return ZF = 0 if true.
i need to invert this value, ie, if ZF = 0 ? ZF = 1 : ZF = 0.
there is a instruction to do that?
Your problem would be trivial if you have used CF flag instead ZF because one instruction
Code:
cmc ; ~ CF (negation of the carry flag)    
does the whole job. Wink
Post 24 Sep 2011, 21:10
View user's profile Send private message Visit poster's website Reply with quote
Teehee



Joined: 05 Aug 2009
Posts: 570
Location: Brazil
Teehee 24 Sep 2011, 22:58
i don't know how to work with CF Sad teach me?

i do a call to a function that returns me ZF 0 if ok. Then i need to invert this value in order to negate the caller return.

see (read comments):
Code:
is_binary:      lodsb
                cmp     al,'0'
                jb      .no
                cmp     al,'1'
                ja      .no
            @@: lodsb
                cmp     al,'0'
                je      @b
                cmp     al,'1'
                je      @b
                cmp     al,'b'
                jne     .no
                call    is_let_or_num  ; if its letter or number (is_let_or_num ZF = 0)
                sete    al             ; i need to say its not a valid binary
                test    al,al          ; (is_binary ZF = 1)
           .no: ret
; return ( ZF ) 0 = is binary


is_let_or_num:  lodsb
                cmp     al,'0'
                jb      .no
                cmp     al,'9'
                jbe     .yes
                cmp     al,'A'
                jb      .no
                cmp     al,'Z'
                jbe     .yes
                cmp     al,'a'
                jb      .no
                cmp     al,'z'
                jg      .no
          .yes: xor     eax,eax
           .no: ret
; return ( ZF ) 0 = is letter or number    

_________________
Sorry if bad english.
Post 24 Sep 2011, 22:58
View user's profile Send private message Reply with quote
Teehee



Joined: 05 Aug 2009
Posts: 570
Location: Brazil
Teehee 24 Sep 2011, 23:42
well, i read the manual and it says XOR clear CF and CMP set CF according to the result. How do i know which results set CF in the CMP instruction?
Post 24 Sep 2011, 23:42
View user's profile Send private message Reply with quote
Teehee



Joined: 05 Aug 2009
Posts: 570
Location: Brazil
Teehee 24 Sep 2011, 23:53
anyway i did a test and CMC works like a charm Wink
Post 24 Sep 2011, 23:53
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 25 Sep 2011, 00:11
Code:
is_let_or_num: ;Using CF instead of ZF to return result
                lodsb
                sub     al, '0'
                cmp     al, '9' - '0' + 1
                jb      .yes
                sub     al, 'A' - '0'
                cmp     al, 'Z' - 'A' + 1
                jb      .yes
                sub     al, 'a' - 'A'
                cmp     al, 'z' - 'a' + 1
          .yes:
           .no: ret    
Post 25 Sep 2011, 00:11
View user's profile Send private message Reply with quote
Teehee



Joined: 05 Aug 2009
Posts: 570
Location: Brazil
Teehee 25 Sep 2011, 12:44
very skilful LocoDelAssembly

i need to use SUB to activate the CF? or it was just a trick
Post 25 Sep 2011, 12:44
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 25 Sep 2011, 15:16
Besides it saves several conditional jumps (which is a good thing), I think it wouldn't be possible otherwise, if "cmp al, '0'" were executed with AL = $0a, it would set the carry flag, so I'd need CMC before returning. So the SUBs are serving a dual purpose, as a well known trick to test if a given number is inside a range, and also as a convenient method to have only the CMPs which set the CF properly.
Post 25 Sep 2011, 15:16
View user's profile Send private message Reply with quote
r22



Joined: 27 Dec 2004
Posts: 805
r22 27 Sep 2011, 18:50
Um why not use a look-up table and TEST
Code:
is_let_or_num:
MOV dl, -1
LODSB
TEST dl, byte[LUT + eax]
RET
    

The look-up table will have either a 0 in the location if you want to return ZF = 1 or a 1 in the location if you want the ZF = 0.

No branches, no SUB tricks. You just have to build your 256 byte LUT.
Post 27 Sep 2011, 18:50
View user's profile Send private message AIM Address Yahoo Messenger Reply with quote
Teehee



Joined: 05 Aug 2009
Posts: 570
Location: Brazil
Teehee 27 Sep 2011, 18:54
oh.. also nice Very Happy
Post 27 Sep 2011, 18:54
View user's profile Send private message Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4046
Location: vpcmpistri
bitRAKE 27 Sep 2011, 19:00
Of course, there is the bitmap method, too. Only uses 32 bytes of data (single cacheline). Only uses a single register.
Code:
    xor eax,eax
    lodsb
    bt [_alphanum],eax
; carry flag is result
    ret    
...might want to inline it.
Post 27 Sep 2011, 19:00
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 27 Sep 2011, 19:17
r22, why using "MOV dl, -1" instead of "TEST byte[LUT + eax], -1"? I mean, it helps on some micro-architectures somehow?

I liked bitRAKE version, and you could also use SBB EAX, EAX to copy CF into ZF if you want to.

Teehee, you may want to search the forum for some more variants (I'm almost sure this isalnum-like stuff has been discussed a lot already), my code was just to show you how to adapt your code to use CF.
Post 27 Sep 2011, 19:17
View user's profile Send private message Reply with quote
r22



Joined: 27 Dec 2004
Posts: 805
r22 27 Sep 2011, 20:03
LocoDelAssembly wrote:
r22, why using "MOV dl, -1" instead of "TEST byte[LUT + eax], -1"? I mean, it helps on some micro-architectures somehow?

No reason.
Post 27 Sep 2011, 20:03
View user's profile Send private message AIM Address Yahoo Messenger Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4347
Location: Now
edfed 27 Sep 2011, 21:16
bitRAKE wrote:
Of course, there is the bitmap method, too. Only uses 32 bytes of data (single cacheline). Only uses a single register.
Code:
    xor eax,eax
    lodsb
    bt [_alphanum],eax
; carry flag is result
    ret    
...might want to inline it.

that's exactlly what i wanted to type when i saw you still made it.

just to follow:
Code:
...
lodsb ;would be better to do it in caller no?
call islet?
jz @f ;no, a letter
call printal ;just in case we want to reuse it, for example
mov al,[edi] ;and because we can load al from anywhere, in the way we want.
call islet?
jnz @f
...
@@:
...
islet?:
;al=char to test
;return zf=1 if letter or num, a num is a letter too.
         movzx eax,al
         bt [.lut],eax
         ret
.lut: ;from the font of my bios
dw 0000 0000 0000 0000
dw 0000 0000 0000 0000
dw 0000 0000 0000 0000
dw 1111 1111 1100 0000

dw 0111 1111 1111 1111
dw 1111 1111 1110 0000
dw 0111 1111 1111 1111
dw 1111 1111 1110 0000

dw 1111 1111 1111 1111
dw 1111 1111 1111 1111
dw 1111 1100 0000 0000
dw 0000 0000 0000 0000

dw 0000 0000 0000 0000
dw 0000 0000 0000 0000
dw 0000 0000 0000 0000
dw 0000 0000 0000 0000


.lut2: ;from the font of my win98 DOS console
dw 0000 0000 0000 0000
dw 0000 0000 0000 0000
dw 0000 0000 0000 0000
dw 1111 1111 1100 0000

dw 0111 1111 1111 1111
dw 1111 1111 1110 0000
dw 0111 1111 1111 1111
dw 1111 1111 1110 0000

dw 1111 1111 1111 1111
dw 1111 1111 1110 0000
dw 1111 1100 0000 0000
dw 0000 0111 0000 0000

dw 0000 0011 0000 0000
dw 1111 1011 1000 0010
dw 1111 1111 1111 0100
dw 0000 0000 0000 0000
    

but it is hard to define what is a letter or not sometimes... $£€éàêëâë, etc...?
Post 27 Sep 2011, 21:16
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page 1, 2  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-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.