Shop OBEX P1 Docs P2 Docs Learn Events
Question re including PASM into SimpleIDE C program — Parallax Forums

Question re including PASM into SimpleIDE C program

twm47099twm47099 Posts: 867
edited 2015-03-08 12:14 in Propeller 1
I learned how to incorporate PASM code from a Spin object (SPIASM.spin) into a C program In this thread:
http://forums.parallax.com/showthread.php/157441-Can-SPI-in-Simple-Libraries-be-speeded-up

One of the things that was explained was that when passing a number of variables to PASM, I could not rely on order of declaration in the C program to be the order the variables were stored in the Hub memory as they would be in a Spin program. I would have to use a structure in the C code. For example:
 typedef struct spipasm_struct               // Structure contains varaibles
 {                                             // for cogs to share + cog & stack
   volatile int command;           
   int Dpin;
   int Cpin;
   volatile int Mode;
   volatile int Bits;
   volatile int Value;
   volatile int Flag;
   int cog;                                    // Remembers cog for spiasm_stop 
 } spia_t;                                    // Data type for struct
  

I am now attempting to write a different program that will only pass one string array (8 bytes) from the C function to the PASM code.
My questions are:
1. Do the elements of an array (string or integer) stay in order in Hub memory in a C program, or can the compiler/optimizer put different elements in different order - In other words do need to use a structure if I'm only transferring one array?

2. If I need to use a structure, how would I declare the array (just once like: char xyz[8]; or ??)

Thanks
Tom

Comments

  • Heater.Heater. Posts: 21,230
    edited 2015-03-07 18:37
    Yes the order of elements in an array in C will be in order in memory. They have to be otherwise pointer arithmetic would not work. So no structure required just pass the address of the array.

    Note that the address of the array is the address of the first element and you can just use the name of the array:

    &myArray[0] == &myArray == myArray
  • Dave HeinDave Hein Posts: 6,347
    edited 2015-03-07 18:44
    The elements of an array always remain in the same order. An array is just a contiguous block of memory, where the elements are addressed as an offset from the beginning of the array.
  • twm47099twm47099 Posts: 867
    edited 2015-03-07 18:55
    Dave and Heater,
    Thanks for the help.

    Tom
  • Dave HeinDave Hein Posts: 6,347
    edited 2015-03-07 18:56
    &myArray is a little different than myArray. If myArray is declared as "int myArray[10]" then myArray will have type "int *" and &myArray will have type "int (*)[10]". The values of myArray and &myArray are the same, but the types are treated differently. I don't think the form &myArray is used very often in C code.
  • DavidZemonDavidZemon Posts: 2,973
    edited 2015-03-08 08:12
    @Heater,

    I think having &myArray in there is dangerous to newcomers. For statically allocated arrays, that might be true. But what if the array is passed into a function? Or it's declared as a pointer instead of an array?
    void foo (char *myArray) {
      // A pointer, so myArray != &myArray;
    }
    
    const char myString[] = "hello world";
    
    // An array in code, so myString == &myString
    foo(myString);
    
  • Heater.Heater. Posts: 21,230
    edited 2015-03-08 09:59
    Guys,

    I do agree. &myArray is not the normal way to do this and is perhaps an error in some cases.

    However the following code compiles and works just fine, give or take some warnings and notes from gcc:
    #include <stdio.h>
    
    char myString[] = "hello world";
    
    void foo (char *myArray) {
        myArray[0] = 'H';
        printf ("%s\n", myArray);
    }
    
    int main()
    {
        // An array in code, so myString == &myString
        foo(&myString[0]);
        foo(myString);
        foo(&myString);
        return 0;
    }
    
    I have some questions:

    1) Despite the warnings can you think of any case where any of those three calls will go wrong?

    2) Given that C makes no attempt at array bounds checking, what is the difference between the type "int *" and the type "int (*)[10]" that Dave pointed out above?

    3) It seems to me that in a sane language calling foo with "myString" would pass a copy of the array to the function in that same way that it does passing an int or float. That is to say pass by value. foo would have no chance to modify the callers copy of the array.

    4) On the other hand calling foo with &myString[0] would pass the address of the char myString[0]. That is pass by reference and gives foo the permission to modify the char at myString[0]. It does not give foo permission to modify anything else within that array though.

    5) Then calling foo with &myString would be a pass by reference of the whole array and foo is given permission to modify any element within it.

    As it happens C does not do what is logical and gives a warning for foo(&myString); which is the more logical interpretation.

    Weird stuff.
  • DavidZemonDavidZemon Posts: 2,973
    edited 2015-03-08 10:41
    Pointers and arrays made a lot more sense to me immediately after I learned about indirect addressing in assembly (it was the 8051 for me). And knowing that, I'm quite happy with how they work in C and C++ - I even think it's intuitive.

    The example of a statically allocated array, like "char myString[] = "hello world"" is a special case. The address of this array is used as a literal in assembly and therefore does not have a pointer variable - which is why &myString == myString (so, in my opinion, &myString should throw a compile error... but that would also be weird and I think the C language writers chose the lesser of two evils).

    Re: pass by value/reference/whatever
    myString is not an array, it's an address. That address is passed by value into foo. Assembly has no concept of an array, so neither does C really.

    The trick to C is to stop thinking of it as a high level programming language, and remember that it is one step up from assembly. Arrays don't exist - they are abstract concepts in C, not native objects. C++ standard library alleviates this and much more of course, but we don't have room for all that magic in the Propeller's hub.

    To answer your questions:
    1) That should work in all cases.
    2) no idea
    3-5) see above

    David
  • Heater.Heater. Posts: 21,230
    edited 2015-03-08 11:13
    SwimDude0614,

    I do appreciate what you are saying. You know me, I like to play with these concepts...
    The example of a statically allocated array, like "char myString[] = "hello world"" is a special case. The address of this array is used as a literal in assembly...
    Well, no. Statically allocated or not should not change the meaning of "char myString[] = "hello world"" in a high level language. Who cares what assembler sees of it?
    myString is not an array, it's an address.
    Also no. I clearly defined myString to be an array of characters containing "hello world". As clearly as "int x = 3" defines x to be an integer containing the value 3.
    It should not be an address, it should be that array of characters containing "hello world" that I defined.
    The trick to C is to stop thinking of it as a high level programming language, and remember that it is one step up from assembly.
    Yes indeed. I found that out in 1978 or there abouts.
    Arrays don't exist - they are abstract concepts in C,...
    Exactly, so why all the fuss about "&myArray" vs "&myArray[0]"" vs "myArray" ?
  • DavidZemonDavidZemon Posts: 2,973
    edited 2015-03-08 11:39
    Ah, I thought you were honestly confused... I didn't realize until about the third time re-writing this reply that you were expressing your opinions of what C should do, not what you think C does. Interesting ideas... I might even agree with them. I don't have the forsight to know what kind of implications that would have on the rest of the spec though.
  • Heater.Heater. Posts: 21,230
    edited 2015-03-08 12:14
    SwimDude,

    Ha, be sure I am honestly confused most of the time :)

    Coming at C from the point of view of an assembly language programmer or one who is intimate with processors and registers and memory it all make perfect sense.

    After learning some Scheme and Haskel and other high level languages you start to look at C and wonder WTF is that all about? Nothing is what it says it is!

    Do I think C should do differently? No. C is a perfect gem as it is. Messing with it leads to C++ or Objective C or many other disasters.
Sign In or Register to comment.