News:

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

USES in a stack frame.

Started by srod, November 28, 2006, 11:58:43 PM

Previous topic - Next topic

srod

Hi,

it's taken me a couple of hours to figure out why some of my code was crashing.  ::)

I eventually tracked it down to the fact that I had placed a USES statement within an automated stack frame, but it was the second statement within the frame as opposed to the first.

I don't understant though why this caused the crash?

The offending code looked like:

nxb_STRINGFROMCONSTANT FRAME SRCSTRING, DSTSTRING
  XOR EAX, EAX
  USES EBX

blah blah


which crashed.

The problem seemed to be that the parameter SRCSTRING did not contain the correct value or perhaps pointed to the wrong part of the stack!

However, when switching the XOR with the USES, everything works fine!

Can someone please explain why? I assume that the order of these statements somehow affects the indexing of the parameters on the stack, but if so, shouldn't EBP have been automatically adjusted by GoAsm after the USES statement?

Ahh, sudden thought!  :eek  Are the labels SRCSTRING etc. in this case being fixed (relative to EBP) before EBP has been set and thus will indeed point to the wrong part of the stack?  If so, I'm wondering if this is a bug?

Thanks in advance for any help.

donkey

Hi srod,

Yes, this is definitely a bug in GoAsm, the decompiled code is as follows...

00401033   55               PUSH EBP
00401034   89E5             MOV EBP,ESP
00401036   31C0             XOR EAX,EAX
00401038   53               PUSH EBX

; blah blah

0040103D   5B               POP EBX
0040103E   5D               POP EBP
0040103F   C2 0800          RETN 8


Which on the surface appears correct, however moving the first parameter into EAX (mov eax,[SRCSTRING]) compiles as follows...

00401039   8B45 0C          MOV EAX, SS:[EBP+C]

Which is ofcourse wrong, it will result in the second parameter being moved. The line should have been compiled as...

00401039   8B45 08          MOV EAX, SS:[EBP+8]

This is ofcourse due to the PUSH EBX being executed after the MOV EBP,ESP when it should be executed before and thereby not moving the stack pointer by 4 bytes at the time the stack frame is constructed when GoAsm expected to to have been moved. The result is that GoAsm miscalculates the offset from EBP by 4 in this case.

The obvious solution, until Jeremy looks into it, is to only have USES as the first statement in a stack frame, something which is generally accepted coding practice.
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

srod

Thanks, I was going nuts for a while!

btw, how did you decompile the code?  Did you use a disassembler or can GoAsm provide such a listing?

Stephen.

donkey

I used OllyDbg to disassemble the code, though GoBug works much better with GoAsm as it is matched to it and outputs in GoAsm syntax which is a big plus. The only real advantage to using Olly is that it has terrific cut and paste features which are useful when you need to display the output here. There is a list file option in GoAsm, just use /L in the GoAsm command line and it will generate a list file, it can be quite useful because it shows the actual source along with the opcodes generated on a line by line basis. It would be nice to have line numbers in the OBJ file (there is a section in the obj specification for them), that way we could do source level debugging of code at run time, I have asked for it but I suspect that it is far too much work for relatively little gain since the list file provides most of the useful info it gives anyway.

Donkey
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

Relvinian

Quote from: donkey on November 30, 2006, 05:09:32 AM
that way we could do source level debugging of code at run time.

That one of my favorite things about using one of the Visual Studio packages (VC6, vs2003 or vs2005) is that I can do source level debugging of all ASM code that I write. Just include the .obj or .lib files into a "template" frame in C/C++ and off I go. I also edit the code during debugging too. I do use VC6 for a lot of timing along with Vtune to optimize the code I write.

Another option VC has that I use but not very often is to have it also compile my .ASM files along with the .cpp files so I don't have to use an external 'something' to compile those .asm.

Relvinian