Hello,
I wrote a program for a 89C51ED2 (using C instructions, not assembler, it's easier for me...); the compilator is OK, but when I use the simulator, I get the error 65 with the return of a sub program to the main one; in the disassembly window, I can see that there is no instruction (just "NOP") at the adress after the RET instruction. I tried to modify some instructions, I get some results, but still the error 65 appears, at different locations of the program.
Some other times, the simulator goes to some used part of the program, but jumping instructions that should precede.
As I do not control the compliling process, I just don't know what to do, and what is hapening.
Does someone understand what is happening, and where I am wrong??
Thanks.
Problem with stac overflow? Watchdog? Uninitialized pointer? Pointer/array access outside bounds? Nested interrupts?
The compiler just creates a program based on valid C instructions. It is up to you to make sure that those instructions forms a valid program. If they don't then the simulator (or the real hardware) will fail to run your application.
you must provide more data; when does it go wrong? if the failure occurs upon return from a function, maybe you have by accident overwritten parts of your stack or modified you return address?
The compiler is not magic?
From all your suggestions, I would rather think of a stack overflow; but I am not sure, as I don't know how to overflow a stack! Do you know how I can verify if the stack is overflow or not, and when? I can see a "SP" and a "SP_max" in the project Work window of µvision, but I don't undestand it
Anyway, it seems like I need to learn more deeply how a MCU works, not just the peripherals and their registers. That's what I understand from your answer. Thank you for it.
Can you just also suggest some links to informations on this subject (not a MCU and its peripherals, but instead its PC, stack, ALU, DPTR, and so on...).
Thank you very much.
OK:
The main program is calling a sub program, in which a SWITCH instruction with 4 cases is used (in each case, the array: BP_Octet[i][j] is updated). After the fourth case, the sub ends, and the RET of the sub program occurs: there happens the error 65, and the program goes to adress where instruction is NOP.
I just noticed something: the 4th case is not completely achieved: the BREAK instruction of this case is not incuded in the debugger lines; if I remove this case, things seems to be better, and there is no more error 65; if I put again this 4th case, and add a 5th case executing a NOP, then the break instruction of the 4th case is included by the debugger, and it is the break of the 5th case that is not included by the debugger (and anyway the 4th case is not well executed).
Here is what I can tell you. I do not see where i am changing a return adress (I just close the sub program with: ")" ) nor how I succeed to overwrite the stack?
A bit of source code is better than a thousand words...
Anyway, are you making sure that all your accesses to BP_Octet[i][j] are valid? If i or j is out-of-bounds, you may overwrite important data.
Are you compiling with optimization? If you have optimized code, then the order of execution may change, making it hard to debug.
Another thing: If the switch block is last in your function, then the last case statement may have a do-nothing break - the fourth case will be the last, followied by one or more end braces before you end the function. The compiler need not perform any break then, since it will notice that the break doesn't change the program flow: The function will end with or without any break statement.
your symptoms sound indeed like, as Per stated, an out-of-bounds error. check you array indexes. did you try to comment your forth case (and possibly, all of your cases)? what happens then? try to isolate the problem.
OK: I send the bit of code. But first, related to the code optimization: I did not set anything; I found something in Project\Options for Target "XXX"\C51\Code Optimisation\Level: 8:Reuse Common Entry Code. Is this a code optimization? As I don't need it, how can I remove code optimization?
The bit of code:
void Scan(void) { for(j = 1; j<=4; j++){ Registre_BP = P0; //reads P0 port// Registre_GPI = P1; //reads P1 port// switch (j) {
case 1: Octet_BP[j][i] = Registre_BP; Octet_GPI[i] = Registre_GPI; break;
case 2: Octet_BP[j][i] = Registre_BP; Octet_RCOD = Registre_GPI; break;
case 3: Octet_BP[j][i] = Registre_BP; break;
case 4: Octet_BP[j][i] = Registre_BP; break;
}; //End switch (j)//
}; //End for(j = 1; j<=4; j++)// }
This sub is called in the Main by:
for (i=1; i<=3; i++) Scan();
Get a C programming book!
In C, an array always starts with index 0, i.e. a 4x4 array as index 0,0 .. 3,3.
Your loop uses j = 1 .. 4. That is a big no-no!
By the way: since I did warn you about possible overwrites of the array, you really, really should have posted the declaration of the array - right now, I can only assume that your array is declared as name[4][4] or something like that.
Yes, it works with the correct indexes.
I'll get a C book...
I should have ask earlier, I would not be that tired now...Anyway, thank you very much to both of you.