:rolleyes:
btw how is this constructed ?
btw how is this constructed ?
I would assume that ELSE would be faster than ELSEIF as the latter doesn't need to execute a comparison. I'm not sure of the exact construction and it varies depending on the type of comparison but it will be something like this :
cmp eax,CONDITION1 ;[b].IF eax == CONDITION1[/b]
jne @F
mov eax,1
jmp ExitTest
@@: ; [b].ELSEIF eax == CONDITION2[/b]
cmp eax,CONDITION2
jne @F
mov eax,2
jmp ExitTest
@@: ; [b].ELSE[/b]
mov eax,3
ExitTest: ; [b].ENDIF[/b]
it is using eax register ?? or maby it's pushing and poping befor and after cmp ?? i wona know more about this.
It uses what you write in the condition. So if you write:
.if ecx == 5
xor eax, eax
.endif
EAX will be set to 0 if ecx is equal to 5.
.if ecx == 5
xor eax, eax
.endif
EAX will be set to 0 if ecx is equal to 5.
.*IF do not modify any registers, only the flag register.
Fastest is writing the jumps yourself, masm does not optimize the conditions (that's what we have compilers for).
Thomas
Fastest is writing the jumps yourself, masm does not optimize the conditions (that's what we have compilers for).
Thomas
Ace,
Unless you are writing a speed critical algo the standard .IF syntax is plenty fast enough, especially if you are only testing a few items at a time.
Its a nice tidy way to handle complex logic and when you need to, it can be nested as well.
Regards,
hutch@movsd.com
Unless you are writing a speed critical algo the standard .IF syntax is plenty fast enough, especially if you are only testing a few items at a time.
.if var == 0
; do this
.elseif var == 1
; do that
.elseif var == 2
; do something else again
.else
; do this instead
.endif
Its a nice tidy way to handle complex logic and when you need to, it can be nested as well.
Regards,
hutch@movsd.com
I think with high lever language MACRO like .if, .else or .elseif have us so must today when write the big soft
Complete in ASM.
Complete in ASM.
Here's a short comparison of what MASM, VC and a human being (me ;)) output for a simple example if/else set:
If one would write this in MASM's HLL constructs, it would look like this:
(Note that we put the parameter in eax first, if we would use instead of eax, all compare instructions would access the memory location because MASM will not modify any registers)
The output of this MASM code is:
This isn't very efficient, MASM doesn't make any attempt to optimize using the conditions' properties. For example, it outputs a 'cmp eax, 1' twice, while a single compare would suffice by sharing it with two jumps. One other thing is the jmp _m3's that will never execute because of the ret instructions before it, but we can forgive MASM this since it does not interpret the meaning of the instructions in between (and it shouldn't). Still, it's wasting bytes for nothing.
The C++ code compiled with VC leads to this:
The code looks a lot like MASM's version but without the useless jumps, and the code now shares one cmp with two jumps.
Naturally, human written code is even better, you could write the above as:
Now only two branches are used which are only predicted wrongly when ecx<2.
Bottom line: never use them in speed critical code, and use a HLL for non-critical code :).
C++
int useless(unsigned int val)
{
if (val==1)
return 0;
else if (val>1 && val<16)
return 1;
else
return 2;
}
If one would write this in MASM's HLL constructs, it would look like this:
mov eax, [esp+4]
.if eax==1
xor eax, eax
ret
.elseif eax>1 && eax<16
mov eax, 1
ret
.else
mov eax, 2
ret
.endif
(Note that we put the parameter in eax first, if we would use instead of eax, all compare instructions would access the memory location because MASM will not modify any registers)
The output of this MASM code is:
mov eax, [esp+4]
cmp eax, 1
jne _m1
xor eax,eax
ret
jmp _m3
_m1:
cmp eax, 1
jbe _m2
cmp eax, 10h
jae _m2
mov eax, 1
ret
jmp _m3
_m2:
mov eax, 2
ret
_m3:
This isn't very efficient, MASM doesn't make any attempt to optimize using the conditions' properties. For example, it outputs a 'cmp eax, 1' twice, while a single compare would suffice by sharing it with two jumps. One other thing is the jmp _m3's that will never execute because of the ret instructions before it, but we can forgive MASM this since it does not interpret the meaning of the instructions in between (and it shouldn't). Still, it's wasting bytes for nothing.
The C++ code compiled with VC leads to this:
mov eax, [esp+4]
cmp eax, 1
jne _m1
xor eax,eax
ret
_m1:
jbe _m2
cmp eax, 10h
mov eax, 1
jb _m3
_m2:
mov eax, 2
_m3:
ret
The code looks a lot like MASM's version but without the useless jumps, and the code now shares one cmp with two jumps.
Naturally, human written code is even better, you could write the above as:
xor eax, eax
mov ecx, [esp+4]
cmp ecx, 1
je _ret
mov eax, 2
jb _ret
cmp ecx, 16
sbb eax, 0
_ret:
ret
Now only two branches are used which are only predicted wrongly when ecx<2.
Bottom line: never use them in speed critical code, and use a HLL for non-critical code :).