Pure Masm32: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?
:biggrin:
mov reg, 1
sub reg, 1
Whoops, misunderstood the question.
I think this works.
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.
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:
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
Thanks, folks.
Quote from: aw27 on November 11, 2017, 08:24:45 PMI 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:
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 ;-)
This is faster and more compact.
pushfd
btc dword ptr [esp], 6
popfd
On my CPU, pushfd is slow: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
May be this is faster:
lahf
xchg al, ah
btc ax, 6
xchg al, ah
sahf
You are pulling my leg ;)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
I believe you are cheating a bit :lol:
setz dl
test dl, dl
TEST changes various flags, not only the ZERO flag.
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?
Quote from: jj2007 on November 12, 2017, 12:40:40 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.
Quote from: aw27 on November 12, 2017, 04:19:03 AMyou 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: