Shop OBEX P1 Docs P2 Docs Learn Events
Assembly language : Please explain the basics first — Parallax Forums

Assembly language : Please explain the basics first

NefastorNefastor Posts: 14
edited 2007-01-03 15:10 in Propeller 1
Hi all,

I should start by mentionning that I don't have the chip yet (it's been ordered, and I live in France) so all I can really do is write and see if my code assembles without error...

My main issue is that of the addressing modes, and how to specify them. A simple example :

How do you load a 32-bit immediate value into a register ? MOV Register,5000 will not work, the assembler indicating that "Source register/constant" cannot exceed $1FF

So far the only solution I have found is to do this :

<...code...>
                  MOV   Register,Constant
<...code...>
<end of code>
Constant    long     5000




Also, it is not explicit whether MOV takes the value located at address "Constant" or the address "Constant" itself

I haven't found any clear indication in the chip's manual of how to specify an addressing mode, and by browsing the examples on this forum I have guessed # is used to specify an immediate value... but then again I'm not sure about how it's resolved by the assembler, for instance if I use :

MOV Register,#Register

My assumption is that this will store the address of Register into Register. Is that true ? Likewise, if I write MOV Register,0 does it store the value at addess 0 into Register, or does it just clear Register ? This really isn't clear to me.

Besides the loading of constants larger than 511, there is also the question of how to address shared RAM :

For instance, suppose I want to write to address 5000 in shared RAM (a random address larger than 511) based on what I've found out so far I'd write something like this :

                  WRLONG   Register, Address
<...code...>
<end of code>
Address     long     5000




But this doesn't work : same error as before.

Page 415 of the manual says wrlong's address operand (s-field) can be either an immediate value or a register : that has lost me. How do I tell wrlong that "Address" is a register, and not the value 5000 located at address "Address" ?

This is really frustrating, please help cry.gif

Jean

Comments

  • Graham StablerGraham Stabler Posts: 2,510
    edited 2007-01-03 11:35
    Hi, I'm not an expert but I'll try to help with a few points.

    You can't do:
       mov   register,#5000
    
    



    Because the whole thing, command source and destination should be a 32bit quantity so as you discovered you can define a initialized local variable and load that in. Note that you could have done:

    constant   res    1
    
    



    and then done constant := 5000 in the spin code before the cog is loaded, that's handy.

    When # is used it means literal so in my example above I put in #5000 because I want the number 5000 to be loaded. You will also see things like:

       jmp   #:loop
    
    



    You want the code to use the text :loop rather than numerically as an address.

    The reason your WRLONG did not work is because you defined your adress in the local/cog memory, instead define it in the VAR block at the top of the spin file.

    I hope that helps some, it is confusing, I have learnt most things by looking at examples that do something like what I want to do for example the mouse code loads data in and out of main memory.

    Graham
  • NefastorNefastor Posts: 14
    edited 2007-01-03 12:23
    Thanks for the reply, Graham.
    Graham Stabler said...

    Note that you could have done:

    constant   res    1
    
    



    and then done constant := 5000 in the spin code before the cog is loaded, that's handy.

    No that's not handy : instead of just one line of code (an immediate load instruction) you now have three lines of code, in two different languages, in three different parts of the code. I'm sure you'll agree it's not easy to write, let alone maintain that kind of code.

    I don't intend to use Spin at all : I have no need for yet another high-level language, especially not an interpreted one. So what you're saying next worries me :
    Graham Stabler said...

    The reason your WRLONG did not work is because you defined your adress in the local/cog memory.

    What does that mean ? That I can only access the first 512 longs of shared RAM from the cogs ?

    There must surely be a way to access shared RAM in a more practical way, especially if you consider you only have 496 longs per cog to store both program and data !

    I'm convinced there's something very easy and very obvious that's eluding me... accessing RAM based on an address stored in a register is something that's so basic it HAS to be possible.

    Jean
  • Graham StablerGraham Stabler Posts: 2,510
    edited 2007-01-03 13:23
    Well even in C if you define a global variable you define it in a different place than the local ones. You might also define it in such a way that its value is not specified until the code is run so I don't really see what the problem is.

    As far as Spin goes it is only an issue if you make it one, I have made no special efforts to learn it but even though most of my applications are better suited to asm anyway I have picked up enough to use it for a few tasks. Firstly assigning some values to a few variables is hardly the worst thing a person has had to do secondly if you want to do anything with graphics or use many of the excellent libraries available you would do well to learn spin even if it is just for debugging. Its won't take long and it is barely a task at all.

    Ah now I see my mistake, I misread what you wrote, you used 5000 as an address in the second example. If you want to do this sort of thing you define your data at the top of the program in the VAR section. When you call the cog with cognew (see you have to use spin) you can pass it the adress to that data, this can be used with wrlong or rdlong and incremented as required. Many people use the feature of self modifying code, that is they will have a command such as wrlong 0,data and before running that code put the relevant adress into the destination field of that command with the movd command.

    Please take a look at mouse.spin

    Notice the variables at the top.

    The start function :
    cognew(@entry, @par_x)
    
    



    Passes the adress of the Par_x variable to the assembly cog.

    In the cog this adress is found in the variable par

    mov                  p,par                   'load input parameters:
                            add     p,#5*4                  '_dpin/_cpin
                            rdlong  _dpin,p
                            add     p,#4
                            rdlong  _cpin,p
    
    



    This code loads the address par into temp variable p then adds the equiv to 5 longs to the address and reads the dpin variable it then jumps one long ahead and reads the cpin variable.

    Of course you could be creating the data not reading it but you can still declare and array in the main ram as you need.

    I can see why you are frustrated, I was. The general program flow and the way cogs use main ram is one of the most un documented parts of the propeller and has lead to much head scratching by me.

    Graham
  • Mike GreenMike Green Posts: 23,101
    edited 2007-01-03 13:33
    Jean,
    You can only access the first 512 locations in shared RAM using an immediate address in the RDxxxx/WRxxxx instructions because any immediate value can only be in the range 0-511. Anything beyond that will have to be stored as a constant or variable in some location with that referenced as a value. You don't have to set locations with SPIN. You can assemble in constant 32 bit values. The reason for mentioning this is that the cog's code is loaded from shared RAM when the cog is initialized and setting values in this initial load is a very useful way to transfer one-time parameters to the cog routine. Many of the I/O drivers use this scheme for configuration information.

    To reiterate, the "#" character in the source field introduces immediate source values. These are used for jump type instructions normally because a jump is implemented as a move to program counter. Shared memory access is done with the RDxxxx/WRxxxx instructions and these ALWAYS take their shared memory byte address from the source field (whether immediate or in some cog memory location). The byte address has the appropriate low order bits ignored so that the alignment of the data in shared memory is correct.
  • NefastorNefastor Posts: 14
    edited 2007-01-03 15:10
    Thanks Graham and Mike, it's starting to get clearer.

    The reason I say I don't want to deal with Spin is the same why I don't use Basic Stamps or VB or anything that is interpreted : I just need the MIPS, even if it means I take longer to write a program. Most of what I do can't run fast enough on an interpreter.

    Of course I understand you can't avoid Spin totally, but I intend to learn just how to start running assembly on cogs. I now see that PAR is more important than I thought. Icould also live with being able to access only the first 512 longs of shared RAM (after all, it's more than enough to implement FIFO's between cogs).

    So basically I'll be using PAR to send my assembly code the base address for arrays in shared RAM. That answers my needs.
    Graham Stabler said...

    I can see why you are frustrated, I was. The general program flow and the way cogs use main ram is one of the most un documented parts of the propeller and has lead to much head scratching by me.
    Graham

    Indeed, the assembly language isn't as well described in the manual as it could be, that's obvious, but hey : it's a new chip, not remotely based on anything that existed before, so it was bound to happen. I figure in the near future the manual will be expanded, books will be written by people with experience (such as yourselves)... it's only unfortunate that I can't wait : I need to get operational very very quickly with the Propeller (I just selected it as a replacement for a FPGA on a couple of projects, if you can imagine that)

    So, I'm thankful for forums and guys like you, keep up the good work ^.^

    Jean
Sign In or Register to comment.