Author Topic: Invert the zero flag  (Read 134 times)

jj2007

  • Member
  • *****
  • Posts: 7628
  • Assembler is fun ;-)
    • MasmBasic
Invert the zero flag
« on: November 11, 2017, 04:35:12 PM »
Pure Masm32:
Code: [Select]
include \masm32\include\masm32rt.inc
LeapYear MACRO arg
  test arg, 3
  .if Zero?
push ecx ; probably a leap year
mov eax, arg
cdq
push 100
idiv dword ptr [esp] ; 0, 4, 8, ..., 96, 0
dec edx ; ********** invert the zero flag  *************
sets dl ; sign set if edx was zero
.if dl ; if year Mod 100 = 0
mov eax, arg
cdq
push 400
idiv dword ptr [esp]
pop eax
test edx, edx ; mod 400 should set zero flag
.endif
pop eax
pop ecx
  .endif
  setz al
  movsx eax, al
  EXITM <eax>
ENDM

.code
start:
  loops=100000000
  push rv(GetTickCount)
  xor ebx, ebx ; year counter
  xor ecx, ecx ; registers to zero
  .Repeat
add ebx, LeapYear(ecx)
inc ecx
  .Until ecx>=loops
  print str$(ebx), " leap years found in "
  invoke GetTickCount
  pop edx
  sub eax, edx
  inkey str$(eax), " ms"
  exit

end start

Question: Is there a better way to invert the zero flag?

hutch--

  • Administrator
  • Member
  • ******
  • Posts: 4866
  • Mnemonic Driven API Grinder
    • The MASM32 SDK
Re: Invert the zero flag
« Reply #1 on: November 11, 2017, 06:37:26 PM »
 :biggrin:
Code: [Select]
mov reg, 1
sub reg, 1
Whoops, misunderstood the question.

I think this works.
Code: [Select]
    mov rdx, 1111
  ; -----------------
    jnz setzeroflag
    mov rdx, 2
    sub rdx, 1          ; set zero flag
    jmp nxt
  setzeroflag:
    mov rdx, 1
    sub rdx, 1          ; clear zero flag
    jmp nxt
  nxt:
  ; -----------------

Don't know if its any faster though.
hutch at movsd dot com
http://www.masm32.com    :biggrin:  :biggrin:

aw27

  • Member
  • ****
  • Posts: 779
Re: Invert the zero flag
« Reply #2 on: November 11, 2017, 08:24:45 PM »
JJ, I don't understand very well your pure MASM32 but I assume you want to "invert", i.e set if reset or reset if set.  8). I think this will do:

Code: [Select]
pushfd
test dword ptr [esp], 40h
.if ZERO?
bts dword ptr [esp], 6h ; set ZF bit of eflags
.else
btr dword ptr [esp], 6h ; reset ZF bit of eflags
.endif
        popfd   


jj2007

  • Member
  • *****
  • Posts: 7628
  • Assembler is fun ;-)
    • MasmBasic
Re: Invert the zero flag
« Reply #3 on: November 11, 2017, 08:44:14 PM »
Thanks, folks.

I assume you want to "invert", i.e set if reset or reset if set

Yes, that is the idea. The LeapYear macro gets edx from the idiv:
Code: [Select]
idiv dword ptr [esp] ; 0, 4, 8, ..., 96, 0
dec edx ; ********** invert the zero flag  *************
sets dl ; sign set if edx was zero

edx assumes values 0, 4, 8, ..., 96, 0, 4, 8, ...

I need the zero flag for edx<>0. For Carry?, there is CMC, Complement Carry Flag, but there is no equivalent for the Zero? flag. Btw it should be fast, pushfd is horribly slow ;-)

aw27

  • Member
  • ****
  • Posts: 779
Re: Invert the zero flag
« Reply #4 on: November 11, 2017, 09:10:37 PM »
This is faster and more compact.

Code: [Select]
        pushfd
btc dword ptr [esp], 6
        popfd   





jj2007

  • Member
  • *****
  • Posts: 7628
  • Assembler is fun ;-)
    • MasmBasic
Re: Invert the zero flag
« Reply #5 on: November 11, 2017, 09:40:31 PM »
On my CPU, pushfd is slow:
Code: [Select]
Intel(R) Core(TM) i5-2450M CPU @ 2.50GHz (SSE4)

2662    cycles for 100 * pushfd
98      cycles for 100 * setxx dl

2656    cycles for 100 * pushfd
96      cycles for 100 * setxx dl

2644    cycles for 100 * pushfd
94      cycles for 100 * setxx dl

2676    cycles for 100 * pushfd
98      cycles for 100 * setxx dl

2647    cycles for 100 * pushfd
93      cycles for 100 * setxx dl

13      bytes for pushfd
11      bytes for setxx dl

aw27

  • Member
  • ****
  • Posts: 779
Re: Invert the zero flag
« Reply #6 on: November 11, 2017, 09:43:19 PM »
May be this is faster:

Code: [Select]
lahf
xchg al, ah
btc ax, 6
xchg al, ah
sahf

jj2007

  • Member
  • *****
  • Posts: 7628
  • Assembler is fun ;-)
    • MasmBasic
Re: Invert the zero flag
« Reply #7 on: November 11, 2017, 10:37:10 PM »
You are pulling my leg ;)
Code: [Select]
Intel(R) Core(TM) i5-2450M CPU @ 2.50GHz (SSE4)

3078    cycles for 100 * pushfd
96      cycles for 100 * setxx dl
803     cycles for 100 * lahf & sahf

2659    cycles for 100 * pushfd
93      cycles for 100 * setxx dl
435     cycles for 100 * lahf & sahf

3478    cycles for 100 * pushfd
99      cycles for 100 * setxx dl
441     cycles for 100 * lahf & sahf

2660    cycles for 100 * pushfd
87      cycles for 100 * setxx dl
442     cycles for 100 * lahf & sahf

2658    cycles for 100 * pushfd
95      cycles for 100 * setxx dl
443     cycles for 100 * lahf & sahf

13      bytes for pushfd
11      bytes for setxx dl
17      bytes for lahf & sahf

aw27

  • Member
  • ****
  • Posts: 779
Re: Invert the zero flag
« Reply #8 on: November 11, 2017, 10:57:37 PM »
I believe you are cheating a bit  :lol:

setz dl
test dl, dl

TEST changes various flags, not only the ZERO flag.

jj2007

  • Member
  • *****
  • Posts: 7628
  • Assembler is fun ;-)
    • MasmBasic
Re: Invert the zero flag
« Reply #9 on: November 12, 2017, 12:40:40 AM »
That is correct. Did i write that i want to change only the zero flag? Are there situations where you would be keen to invert a single flag but keep all others?

aw27

  • Member
  • ****
  • Posts: 779
Re: Invert the zero flag
« Reply #10 on: November 12, 2017, 04:19:03 AM »
Did i write that i want to change only the zero flag?
LOL  :lol:
When police is looking for a killer are they allowed to shoot everyone else nearby?

Quote
Are there situations where you would be keen to invert a single flag but keep all others?
You have the burden of the proof because you are making a controversial statement, i.e, Intel populated the chip with useless flags.

jj2007

  • Member
  • *****
  • Posts: 7628
  • Assembler is fun ;-)
    • MasmBasic
Re: Invert the zero flag
« Reply #11 on: November 12, 2017, 05:39:33 AM »
you are making a controversial statement, i.e, Intel populated the chip with useless flags.

You seem to be hungry, José, but I am not in the mood to feed you :icon_mrgreen: