# MPLAB simulator skips instructions when single stepping

#### simonbramble

##### Active Member
Long story short... I have picked up my PIC development kit after 10 years. I downloaded MPLAB X and installed it. It keeps crashing on startup, so I uninstalled it and reinstalled MPLAB V8.46. Code compiles, using Hi Tech PICC compiler

However, when single stepping through my code, it jumps over one line of code. See below

Code:
void lcd_initialise(void)                /* initialise LCD */
{
unsigned char n, data;

setbit(global, 1);                    /* indicate 1x 4 bit transfer*/

for(n=0; n<10; n++)
{
delay_10ms();                    /* wait for power to stabilise*/
}

for (n=0; n<3; n++)
{
data = 0b00110000;          // it ignores this line and skips straight to the lcd_write()
lcd_write(data);
}
It comes out of the delay_10ms() routine, then immediately steps to the lcd_write() routine, bypassing the 'data = ' line thus loading garbage into the lcd_write() routine and not initialising the LCD

What am I doing wrong? It simulated well in MPLABx, but this takes 1.5 hours to install and crashes on startup.

I'm all ears (and heart)

Thanks - Simon

#### Pommie

##### Well-Known Member
Have you compiled the code? If you're stepping through old code then it can do strange things like that.

Mike.
Compiled = recompiled.

#### tumbleweed

##### Active Member
MPLAB V8.46
The last version of MPLAB was 8.92, so 8.46 is older than ancient.

#### simonbramble

##### Active Member
Have you compiled the code? If you're stepping through old code then it can do strange things like that.
Yes I have compiled the code. It worked perfectly when I used MPLab years ago, but not now. OK my laptop and OS have changed since then. I have compiled and recompiled plenty of times in the last few days.

Anyone have a URL where I can download MPLAB 8.92...? although I think it is the compiler that is at fault and not MPLAB

#### Ian Rogers

##### User Extraordinaire
Forum Supporter
Yep.. Pretty normal... The coff file may be 1 line out... If the editor doesn't see's 'data = 0b00110000; ' but the closing brace '}'

I normally place a Nop(); before the line to check that it is...

#### tumbleweed

##### Active Member
I think you have to have a microchip account now... I don't think there's a direct link anymore.

If you think it's just the compiler then open a disassembly window and see if there's code at that line.
Also, try setting a breakpoint on that line. If the instruction isn't there you shouldn't be able to.

The compiler may have rearranged/optimized that code since there's no reason for that statement to be in the loop.

#### simonbramble

##### Active Member
Yep.. Pretty normal.
If I insert a nop, the program works. I guess I was being stubborn and saying 'this darn thing should work without me needing to bodge my code'

If you think it's just the compiler then open a disassembly window and see if there's code at that line.
Also, try setting a breakpoint on that line. If the instruction isn't there you shouldn't be able to.
I opened the disassembly window and there is no code at that point, so it looks like that line has been 'optimised out'. Any ideas as to how to 'optimise it back in' again?

#### gophert

##### Well-Known Member
What is the value of "data" in the LCD_write("data") command?
The compiler May have optimized out the data= 0b00110000; because it is a constant. Is LCD_write(0b00110000);?

#### tumbleweed

##### Active Member
if the compiler did optimise it, the code for setting 'data' should be before the loop executes,
assuming it's still using 'data' as gophert points out.

#### Ian Rogers

##### User Extraordinaire
Forum Supporter
What is the value of "data" in the LCD_write("data") command?
The compiler May have optimized out the data= 0b00110000; because it is a constant. Is LCD_write(0b00110000);?
Jings…. Missed that.... Even the crappiest optimiser would see that one...

#### simonbramble

##### Active Member
Code:
    for (n=0; n<3; n++)
{
data = 0b00110000;          // it ignores this line and skips straight to the lcd_write()
lcd_write(data);
}
and

What is the value of "data" in the LCD_write("data") command?
The compiler May have optimized out the data= 0b00110000; because it is a constant. Is LCD_write(0b00110000);?
OK for the slow ones at the back (me) what have I missed? I am assigning the value of 0b00110000 to 'data' then reading it into the LCD using lcd_write.

If I assign that value to data inside or outside of the for() loop, what difference does it make?

This exact code works perfectly well in MPLAB X (that I have now got working without crashing on startup)

What have I done wrong?

Jings…. Missed that.... Even the crappiest optimiser would see that one...
This comment makes me feel like I am really missing something obvious. Don't be afraid to use monosyllables and talk me through it slowly please...

#### simonbramble

##### Active Member
It also ignores the 'data = ...' lines in the following code too - and these have no for() loops

Should I be defining the data variable with Volatile or some such other keyword?

Code:
    /* function set */
data = 0b00100000;
lcd_write(data);

clearbit(global, 1);                /* indicate 2x 4 bit transfer */

lcd_write(data);
data = 0b00101000;                    /* N= 1; F=0 */
lcd_write(data);
/* display off */
data = 0b00001000;
lcd_write(data);
/* display clear */
data = 0b00000001;
lcd_write(data);
/* entry mode set */
data = 0b00000110;                    /* I/D = 1 S = 1 */
lcd_write(data);
/* display on */
data = 0b00001100;
lcd_write(data);

#### Pommie

##### Well-Known Member
There is no point in assigning the data to a variable (data in your case) so the compiler optomises out that line and substitutes lcd_write(0b00101000); as it's more efficient.
The adding a NOP works because the compiler can't know what the assembly instruction did so it can't optimise.

Mike.

#### gophert

##### Well-Known Member
Since two instructions are next to each other, you are saying
Data = 35;
LCDWrite(data);

That is like giving your brother 35 cents so he can hand it to the cashier. Just give the cashier 35 cents. That is, save yourself one line of code
LCDWrite(35);

Your compiler can see that you are just going to use the "data" variable one time at the current value so it doesn't bother setting the variable, it just passes the value.

When you put the nop() in between, your are fooling the optimizer in the compiler (at least the optimizer in the free compiler). The nop() is like putting a curtain between you and the cashier so she doesn't know you handed money to your brother.

#### simonbramble

##### Active Member
Pommie gophert : Thanks for your inputs. I would not have thought it made any difference, but obviously the compiler is clevererer than I thought. Now I see the error of my ways and I really appreciate the help, as always.

Code is going better now.

Finally, I dont have a brother and if I did, I would not give him my pocket money.

I've got short arms and deep pockets

Stay safe - Simon