News:

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

CMP not working as expected

Started by bigmacx, June 02, 2008, 06:40:03 AM

Previous topic - Next topic

bigmacx

I'm debugging the following code

MOV dword ptr[ebp - 24H], eax     // value in eax is 0xd0005500
CMP  dword ptr[ebp - 24H], 0
JE     blahhhh

Now it always takes the jump but because the CMP instruction sets the zero flag. However I thought that CMP simply subtracted the source from the dest - so how does (0 - 0xd0005500 == 0)?

Do I have the cmp instruction wrong? Is it producing a negative value which is being clamped to zero?

Thanks for any help,

Mac.




hutch--

Substitute this and see if it works.


test eax, eax
jz label


While its hardly good code you are debugging,your results don't make sense. JE is neither signed OR unsigned so it should branch id EQUAL.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

bigmacx

Quote from: hutch-- on June 02, 2008, 08:01:57 AM
Substitute this and see if it works.


test eax, eax
jz label


While its hardly good code you are debugging,your results don't make sense. JE is neither signed OR unsigned so it should branch id EQUAL.

Thanks for the response Hutch, it doesn't make sense to me either. I can't change the code since it's not mine, it's part of the Microsoft Direct Draw WinCE 6.0 implementation. I pass an address back to it (value in EAX) and then it returns a failure back to the API. When I debugged it to try and work out why, this looked like the offending code. The best I can tell it's doing NULL check on the memory address but the check is always failing.

I tried changing the value in eax to 0 and it *still* took the jump - really confused now. It doesn't seem matter what I pass to the CMP instruction it always sets the zero flag.

Mac.

jj2007

Trying to emulate the code, but no success either...

include \masm32\include\masm32rt.inc

.code

;read-only data before start
AppName     db "Test app:", 0

start:
invoke MessageBox, 0, chr$("Int 3?"), addr AppName, MB_YESNO
.if eax==IDYES
int 3
.endif

call TestWin
invoke ExitProcess, 0

TestWin proc
LOCAL a,b,c1,d,e,f,g,h,i,j

mov i, 0d0005500h
cmp [i], 0
je IsEqual
invoke MessageBox, 0, chr$("not equal"), addr AppName, MB_OK
ret
IsEqual:
invoke MessageBox, 0, chr$("is equal"), addr AppName, MB_OK
ret
TestWin endp

bigmacx

Thanks for looking at this.

My only thought now is that the debugger is not giving me a true representation of what is happening. Perhaps there's some out of order instruction execution going on and by the time I've edited the values the expression has already been evaluated. It seems unlikely but I can't think of anything else.

Regards,

Mac.

hutch--

Mac,

Just dead list it (decompile the code) and see if its the same as you were getting in the debugger.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

bigmacx

Hi Hutch,
when I said instruction reordering I meant by the CPU not the compiler. If that's the case then there's little I can do about it - apart from trying to edit the register value even earlier (ie. before the CMP instruction enters the pipeline).
I seriously doubt this is what's happening, just can't think of any other explanation at the moment.

Mac.

hutch--

Mac,

Instruction reordering occurs in the pipeline stage, they come out the back end and are retired in the correct order so you don't have to worry about that aspect of instruction scheduling. Without this garrantee of instruction ordering code would not run so you have nothing to worry about here.

the couple of instructions you posted test eax to see if its zero, its a poor technique which is probably either poor compiler optimisation or perhaps the use of a LOCAL in the compiler where it did not need to be done.

It may be the case that you have not recognised the correct piece of code, its easy enough to do in messy looking compiler code.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

jj2007

Below Olly V2 listing, behaving as expected. You are absolutely sure that eax is non-zero in that moment?

CPU Disasm
0040101C    ³? B8 005500D0    mov eax, D0005500
00401021    ³? 8945 DC        mov dword ptr [ebp-24], eax
00401024    ³? 837D DC 00     cmp dword ptr [ebp-24], 0
00401028    ³. 74 15          je short wrong_JE.0040103F  ; ÚExitCode = 4198463.
0040102A    À. 6A 00          push 0                      ; ÀKERNEL32.ExitProcess
0040102C     ? 68 00104000    push wrong_JE.00401000      ; ASCII "Test app:"
00401031    ³? 68 1E304000    push offset wrong_JE.004030 ; ASCII "not equal"
00401036    ³? 6A 00          push 0
00401038    ³? E8 17000000    call <jmp.&user32.MessageBo ; Jump to user32.MessageBoxA
0040103D    ³? C9             leave
0040103E    ³? C3             retn
0040103F    ³? 6A 00          push 0
00401041    ³? 68 00104000    push wrong_JE.00401000      ; ASCII "Test app:"
00401046    ³? 68 28304000    push offset wrong_JE.004030 ; ³ASCII "is equal"
0040104B    ³? 6A 00          push 0                      ; ³
0040104D    ³? E8 02000000    call <jmp.&user32.MessageBo ; ³Jump to user32.MessageBoxA



bigmacx

Quote from: jj2007 on June 02, 2008, 12:25:37 PM
Below Olly V2 listing, behaving as expected. You are absolutely sure that eax is non-zero in that moment?

Yep definitely, eax and the memory location [ebp - 24h] both show the same non-zero value. Then again I am assuming that the debugger is telling me the truth about the register and memory contents. I just tried a complete OS recompile to make sure the symbols were matching and got the same result - thanks for looking into it though.

I should probably point out that I'm remote debugging this, I guess it could be something to do with the WinCE platform builder not showing me the correct information - some latency caused by the remote link perhaps?

I'm pretty sure it's not the code now but some WinCE/Platform-Builder artifact, I've posted a question on one of the WinCE forums so I'll see where that gets me.

Hatch - thanks for the info about the CPU pipeline. My knowledge of CPU architecture isn't exactly comprehensive.

Thanks again,

Mac.











jj2007

Quote from: bigmacx on June 02, 2008, 12:36:40 PM
I should probably point out that I'm remote debugging this, I guess it could be something to do with the WinCE platform builder not showing me the correct information

That is one track to keep an eye on. Sometimes (often?) MS uses the same old source code for different platform-specific API's. Can you test your code on XP instead of CE, and debug it directly?