NatKarmios
Posts: 5
Joined: Sun Jun 16, 2019 1:50 am

Unexpected behaviour of arrays and switch statements

Sun Jun 16, 2019 2:02 am

I currently have a simple program that sets up a framebuffer that can be written to.

I am encountering behaviour where values stored i arrays, once retrieved, come back as seemingly random values, with no relation to the originals.
I have also noticed some similarly strange and.unexpected behaviour from switch statements - I suspect this has something to do with how both arrays and switch statements are statically allocated in memory.

As an example, here I have some code that should draw a hardcoded number, followed by 7 other hardcoded numbers that have been stored in an array:

Code: Select all

int cols[7] = { 0xFFFF0000, 0xFFFF7F00, 0xFFFFFF00, 0xFF00FF00, 0xFF0000FF, 0xFF4B0082, 0xFF9400D3 };
drawNum(&display, 0x1234ABCD);
for (int i=0; i<7; i++)
  drawNum(&display, cols[i]);
And this is the result (note that text is drawn from the bottom upwards):
Image

As you can quite clearly see, all the array-stored values come back as wildly different to what is expected.

Is this a known problem? Anyone know of a workaround or a solution?

Many thanks for your time.

lpoulain
Posts: 24
Joined: Mon May 20, 2019 12:35 am

Re: Unexpected behaviour of arrays and switch statements

Sun Jun 16, 2019 4:37 am

One thing I notice is that you are using an int type (so signed integers), but have numbers in your array which are negative numbers. You might want to use unsigned integers instead.

NatKarmios
Posts: 5
Joined: Sun Jun 16, 2019 1:50 am

Re: Unexpected behaviour of arrays and switch statements

Sun Jun 16, 2019 9:48 am

lpoulain wrote:
Sun Jun 16, 2019 4:37 am
One thing I notice is that you are using an int type (so signed integers), but have numbers in your array which are negative numbers. You might want to use unsigned integers instead.
Good spot, though unfortunately this has no effect. I expect this is because drawNum() uses bitwise logic.
Last edited by NatKarmios on Sun Jun 16, 2019 10:29 am, edited 1 time in total.

NatKarmios
Posts: 5
Joined: Sun Jun 16, 2019 1:50 am

Re: Unexpected behaviour of arrays and switch statements

Sun Jun 16, 2019 9:55 am

An interesting development; if I assign the array values at runtime like so:

Code: Select all

unsigned int cols[7];
cols[0] = 0xFFFF0000;
cols[1] = 0xFFFF7F00;
cols[2] = 0xFFFFFF00;
cols[3] = 0xFF00FF00;
cols[4] = 0xFF0000FF;
cols[5] = 0xFF4B0082;
cols[6] = 0xFF9400D3;
drawNum(&display, 0x1234ABCD);
drawNum(&display, (int)cols);
for (int i=0; i<7; i++)
  drawNum(&display, cols[i]);
...then the numbers are rendered fine. Potentially something at compile-time messing this up?

LdB
Posts: 1209
Joined: Wed Dec 07, 2016 2:29 pm

Re: Unexpected behaviour of arrays and switch statements

Sun Jun 16, 2019 3:27 pm

Most likely your linker file isn't saving the rodata section which is the one the constant data will go into, so basically your file doesn't actually contain the constant array and is printing junk.

Without changing the linker file try putting the array in the text section ... something like

Code: Select all

int  __attribute__((section("text"))) cols[7] = { 0xFFFF0000, 0xFFFF7F00, 0xFFFFFF00, 0xFF00FF00, 0xFF0000FF, 0xFF4B0082, 0xFF9400D3 };

Nabushika
Posts: 1
Joined: Sun Jun 16, 2019 5:47 pm

Re: Unexpected behaviour of arrays and switch statements

Sun Jun 16, 2019 5:48 pm

LdB wrote:
Sun Jun 16, 2019 3:27 pm
Most likely your linker file isn't saving the rodata section which is the one the constant data will go into, so basically your file doesn't actually contain the constant array and is printing junk.

Without changing the linker file try putting the array in the text section ... something like

Code: Select all

int  __attribute__((section("text"))) cols[7] = { 0xFFFF0000, 0xFFFF7F00, 0xFFFFFF00, 0xFF00FF00, 0xFF0000FF, 0xFF4B0082, 0xFF9400D3 };
This didn't work, data was still garbled. Any other suggestions? Or anything we can do to fix the linking?

NatKarmios
Posts: 5
Joined: Sun Jun 16, 2019 1:50 am

Re: Unexpected behaviour of arrays and switch statements

Sun Jun 16, 2019 7:13 pm

LdB wrote:
Sun Jun 16, 2019 3:27 pm
Most likely your linker file isn't saving the rodata section which is the one the constant data will go into, so basically your file doesn't actually contain the constant array and is printing junk.

Without changing the linker file try putting the array in the text section ... something like

Code: Select all

int  __attribute__((section("text"))) cols[7] = { 0xFFFF0000, 0xFFFF7F00, 0xFFFFFF00, 0xFF00FF00, 0xFF0000FF, 0xFF4B0082, 0xFF9400D3 };
This has no effect :(
Seemingly random numbers are still displayed.

lpoulain
Posts: 24
Joined: Mon May 20, 2019 12:35 am

Re: Unexpected behaviour of arrays and switch statements

Sun Jun 16, 2019 11:59 pm

What happens if you try the following scenarios:

Code: Select all

drawNum(&display, 0xFFFF0000);

Code: Select all

int cols[0] = { 0x1234ABCD };
drawNum(&display, cols[0]);
Other things you can try:
  • If you are using UART, print the array numbers there at various point of your program to see if they are defined properly at one point
  • Perform a memory dump of your array to make sure it contains the right data.
  • Disassemble your code (objdump -d -S yourfile.o)

LdB
Posts: 1209
Joined: Wed Dec 07, 2016 2:29 pm

Re: Unexpected behaviour of arrays and switch statements

Mon Jun 17, 2019 6:45 am

I suspect we need to see your linker file and the function drawNum because it is obviously having issues with constant arrays.

NatKarmios
Posts: 5
Joined: Sun Jun 16, 2019 1:50 am

Re: Unexpected behaviour of arrays and switch statements

Mon Jun 17, 2019 9:52 am

LdB wrote:
Mon Jun 17, 2019 6:45 am
I suspect we need to see your linker file and the function drawNum because it is obviously having issues with constant arrays.
The linker file:
https://gist.github.com/NatKarmios/9a15 ... 4770797dae

I highly doubt drawNum() is having an effect, but here it is just in case:

Code: Select all

void drawNum(display_t *display, unsigned int num) {
  int y = display->height - (display->debugLinesPrinted*7);

  for (int i=0; i<8; i++) {
    int numData = getNumData((num >> (28-(4*i))) & 0xF);
    drawChar(display, i*6, y, numData);
  }

  newLine(display, 8);
}

LdB
Posts: 1209
Joined: Wed Dec 07, 2016 2:29 pm

Re: Unexpected behaviour of arrays and switch statements

Mon Jun 17, 2019 12:30 pm

That should work, I cant see any problem.

I guess it has to be a weird compiler bug have you checked for updates?

You could try the other three ways to write the array

Code: Select all

static const int  cols[7] = { 0xFFFF0000, 0xFFFF7F00, 0xFFFFFF00, 0xFF00FF00, 0xFF0000FF, 0xFF4B0082, 0xFF9400D3 };
static int  cols[] = { 0xFFFF0000, 0xFFFF7F00, 0xFFFFFF00, 0xFF00FF00, 0xFF0000FF, 0xFF4B0082, 0xFF9400D3 };
static const int  cols[] = { 0xFFFF0000, 0xFFFF7F00, 0xFFFFFF00, 0xFF00FF00, 0xFF0000FF, 0xFF4B0082, 0xFF9400D3 };

Return to “Bare metal, Assembly language”