X-Authentication-Warning: delorie.com: mail set sender to djgpp-bounces using -f From: Paul Wilkins User-Agent: Mozilla Thunderbird 0.6 (Windows/20040502) X-Accept-Language: en MIME-Version: 1.0 Newsgroups: comp.os.msdos.djgpp Subject: Re: assembly code of the "strange error" - program References: <20040727041413 DOT 21318 DOT 00000463 AT mb-m18 DOT aol DOT com> In-Reply-To: <20040727041413.21318.00000463@mb-m18.aol.com> Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Lines: 85 Message-ID: Date: Tue, 27 Jul 2004 21:25:54 +1200 NNTP-Posting-Host: 218.101.50.29 X-Complaints-To: abuse AT tsnz DOT net X-Trace: news02.tsnz.net 1090920374 218.101.50.29 (Tue, 27 Jul 2004 21:26:14 NZST) NNTP-Posting-Date: Tue, 27 Jul 2004 21:26:14 NZST Organization: TelstraClear To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Reply-To: djgpp AT delorie DOT com Sterten wrote: > OK, here is the assembly listing (excerts) for the "strange error" program. > I haven't yet figured out, what exactly went wrong > and why small program changes cause to program to terminate > without error. > > > > here is, what was printed with > gcc -c -g -Wa,-a,-ad -O2 qser3.c > > I removed some lines (...) which appeared nonimportant to me > to reduce this posting. > The output is rather ugly, because many instructions require more than line > and because of the the ATT-assembly-code. > BTW. why is it used ? Is it easier for the disassembler or for historical > reasons or ? > The critical section, where it crashed starts below at > > 81:qser3.c **** m55:r--;if(R[r]!=1)goto m55; > 542 .loc 1 81 0 > > > apparantly R is the variable with smallest address, so what > stands before R and why is it affected by small > changes in the program ? R[r] is looping with the r index being reduced by one each time, so the program is accessing R[3], R[2], R[1], R[0], and then on to R[-1], R[-2], etc.. Most people will now be feeling a sense of horror, at seeing negative array indexes, because arrays ARE NOT supposed to have negative indicies. The following is a quote from a C manual that I currently have to hand. "One of the most coimmon and troublesome errors in C programming occurs when an index value goes out of range for an array - that is, when an index value is less than zero or greater than the size of the array minus one." So when you have int R[99]={0}; your range is R[0], R[1], R[2], etc..., R[97], R[98] There is no R[99] element because the line "int R[99];" says that you want 99 elements, so C uses for its 1st element R[0]. The second element is R[1], the 98th element is R[97] and the 99th element is R[98] You are not supposed to access R[99] or higher, or R[-1] or lower. To get back to your question, what is going wrong is that R[r] is trying to access negative indicies (the r value). At first C lets you do that even though you're not supposed to, because C give you enough rope with which to hang yourself. As r gets lower and lower you are moving from memory areas that you are not supposed to access, to memory areas that you are not ALLOWED to access (the General Protection Fault), which is why the crash occurs. Why your program sometimes crashes with one compile time option and not wqith other options, is because the part that is crashing is walking backwards through memory looking for a "1" value. Some compiled versions may have that somewhere in the unused parts of data block, and some may not have it. My question for you is, where to from here. Are you wanting to fix this so that it just doesn't happen, or are you wanting to delve a lot deeper into assembly language. Trivia: When defining arrays the contents are determined in different ways. int R[99]; // won't be initialised and will have different values int S[99]={1}; // S[0]==1, S[1] to S[98] are set to 0. int T[99]={1,2,3}; // sets T[0]==1, T[1]==2, T[2]==3, others are 0. Now check this out. int U[99]; memset(U, 4, sizeof(U)); memset fills the memory locations used by U with the value 4. -- Paul Wilkins