News:

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

crash when moving value to esp

Started by sefaen, December 28, 2008, 04:35:57 AM

Previous topic - Next topic

sefaen

When I run the following program Windows gives me this error:

sixtyfourBit.exe has stopped working:
A problem caused the program to stop working correctly.
Windows will close the program and notify you if a solution is available.

Visual Studio gives me an option to debug.

JIT Debugger reports:

Unhandled exception at 0x040013e3 in sixtyfourBit.exe: 0xC0000005: Access violation writing location 0xfffffffb.

This is my code (very simple I know).


program sixtyfourBit;

#includeonce ("stdlib.hhf")
#includeonce ("hide/hidelib.hhf")
#includeonce ("macros/macros.hhf")
#includeonce ("macros/extensions.hhf")

?@nodisplay := true;
?@noalignstack := true;

begin sixtyfourBit;

//1-bit registers
//none
//bit
//2^1 = 2 values
//unsigned range 0 to 1
//signed range -1 to 0

//2-bit registers
//none
//none
//2^2 = 4 values
//unsigned range 0 to 3
//signed range -2 to +1

//4-bit registers
//none
//nibble
//2^4 = 16 values
//unsigned range 0 to 15
//signed range -8 to +7

//8-bit registers
//al,ah,bl,bh,cl,ch,dl,dh
//byte/half-word (consists of two nibbles)
//2^8 = 256 values
//unsigned range 0 to 255
//signed range -128 to +127
mov (255, al);
stdout.put("al=", al, nl);
mov (255, ah);
stdout.put("ah=", ah, nl);
mov (255, bl);
stdout.put("bl=", bl, nl);
mov (255, bh);
stdout.put("bh=", bh, nl);
mov (255, cl);
stdout.put("cl=", cl, nl);
mov (255, ch);
stdout.put("ch=", ch, nl);
mov (255, dl);
stdout.put("dl=", dl, nl);
mov (255, dh);
stdout.put("dh=", dh, nl);

//16-bit registers
//ax,bx,cx,dx,si,di,bp,sp
//word (consists of two bytes/four nibbles)
//2^16 = 65536 values
//unsigned range = 0 to 65535
//signed range = -32768 to +32767
mov (65535, ax);
stdout.put("ax=", ax, nl);
mov (65535, bx);
stdout.put("bx=", bx, nl);
mov (65535, cx);
stdout.put("cx=", cx, nl);
mov (65535, dx);
stdout.put("dx=", dx, nl);
mov (65535, si);
stdout.put("si=", si, nl);
mov (65535, di);
stdout.put("di=", di, nl);
mov (65535, bp);
stdout.put("bp=", bp, nl);
mov (65535, sp);
stdout.put("sp=", sp, nl);

//32-bit registers
//eax,ebx,ecx,edx,esi,edi,ebp,esp
//double-word/long-word (consists of two words/four bytes/eight nibbles)
//2^32 = 4294967296 values
//unsigned range 0 to 4294967295
//signed range -2147483648 to +2147483648
mov (4294967295, eax);
stdout.put("eax=", eax, nl);
mov (4294967295, ebx);
stdout.put("ebx=", ebx, nl);
mov (4294967295, ecx);
stdout.put("ecx=", ecx, nl);
mov (4294967295, edx);
stdout.put("edx=", edx, nl);
mov (4294967295, esi);
stdout.put("esi=", esi, nl);
mov (4294967295, edi);
stdout.put("edi=", edi, nl);
mov (4294967295, ebp);
stdout.put("ebp=", ebp, nl);
mov (4294967295, esp);
stdout.put("esp=", esp, nl);

//64-bit registers
//rax,rbx,rcx,rdx,rsi,rdi,rbp,rsp
//quad-word (consists of two double-words/fours words/eight bytes/sixteen nibbles)
//2^64 = 18446744073709551616 values
//unsigned range 0 to 18446744073709551615
//signed range -9223372036854775808 to 9223372036854775807

end sixtyfourBit;



Program runs fine when I comment out the mov to sp and esp registers:



...

//mov (65535, sp);

...

//mov (4294967295, esp);

...



--

Intel Core 2 Duo T5450 @ 1.66Ghz
3GB DDR2

Windows Vista Home Premium (32-bit)
HLA v1.99
MASM32 v1.00
HIDE 1.31.02

BogdanOntanu

ESP register (and his lower part named SP) are normally used as stack pointer. This means that the return address from a CALL to a procedure /function is stored in a relative postion to ESP. Also in Win32 API the parameters for STDCALL API are pushed on the stack and LOCAL variables used in procedures/functions are also on the stack and accessed by an EBP relative stack frame.

Hence ESP and EBP are "normally" used by the system and have special purposes. They are not "general purpose registers" and the OS or the application does need them to have valid values (valid= in between some acceptable ranges) or an error will raise.

In you case the value 65536 is too small for ESP (probably there is no memory mapped by the OS at that low address) and hence at the first attempt to return from a function a crash is generated by either trying to read the return address from an non mapped memory area OR even worst by obtaining the wrong return address.

The same is true for the huge value placed in ESP. At that address (4G ?) the OS has it's own structures (if any) and your application does not have the right to read or write...not to mention the wrong return address that can be "extracted" from that location.

While you are learning, read a little about what purpose every register "normally" has. For a start ESP and to some extent EBP should be "off limits" for you. Understand what they are used for but avoid "touching" them until you get more experienced.

You can play freely with EAX, ECX, EDX, EBX, ESI, EDI because they are "general purpose" registers.

However take care because in a "modern protected OS" like Windows or Linux or Unix you can not read or write to whatever memory address you like. The OS does restrict your rights to what is considered beneficial.
Ambition is a lame excuse for the ones not brave enough to be lazy.
http://www.oby.ro

sefaen

Thanks for the quick reply. I'll try studying the individual registers more carefully.