I am currently debugging a very old game (so there is no customer support) that keeps crashing under certain condition and I have found out it is because unsigned short to unsigned int conversion was done by signed conversion (possibly code similar to "short int x = 0x8000; unsigned int y = (unsigned int)x" which leads to y = 0xffff8000 instead of 0x00008000)
Now I have to debug the game in disassembly code to find out all the movsx command that does the wrong conversion and change them to movzx command (there are many places where signed conversion is correct too so I cannot just change all movsz to movzx).
The problem is, when I am at a crashing frame (where another function tries to access the address 0xffff8000, for example), that crashing function might be miles away from the original movsx code that does the conversion. The crashing function (and its callers) is called thousands of times so it is not possible to put a break point at some point before and see how the register value changes. It appears that, for every time I run the program, the stack address is different from the previous run, so data breakpoints does not work as well since I don't know which address to break on before the crashing happens.
I need a good way (a way that has 100% of chance to find the bug in relatively consistent time) to find out when does the value 0xffff8000 is pushed onto the stack. If someone with experience in asm debugging can give me some techniques to achieve this I will really appreciate.
EDIT: (Although the question in the title is still not answered, the following information I found, which helps me fixed the specific scenario, might be useful to someone in the future)
I have found out that Visual Studio gives the wrong call stack sometimes. It seems to find the callstack based on stack pointer value searching, so if a function start with something like "sub esp,2Ch" then the callstack will be screwed up.
To debug this issue one needs to manually set a breakpoint before the crash, with condition that the register is at the wrong value, and when it is hit one needs to manually modify the register to the correct value; after that execute the function until it ends and see where it returns to.