Shop OBEX P1 Docs P2 Docs Learn Events
Still struggling to understand Assembly — Parallax Forums

Still struggling to understand Assembly

3dogpottery3dogpottery Posts: 78
edited 2013-01-03 11:39 in Propeller 1
In an attempt to understand Assembly, I’ve been struggling with SPI_Asm.spin. With some help from member MagIO2,
I was able to make some progress, but very little. After struggling for several days, I am again going to appeal for some help.

The assembly code first fills an array of five registers with parameters passed by either a shift in or shift out subroutine.
I understand how that works. Next, the code looks up the command address. I believe it does this by examining the bit passed via “par”.

Par contains the address to the variable “command” which is set like this:

command := cmd << 16 + argptr ‘Where “cmd” is a “1” or a “2”, for “shift out” or “shift ‘in”,
'and “argptr” is the address of the first of the five ‘parameters.

My confusion starts immediately back in the assembly routine where the bits representing “cmd” are shifted right 18 places instead of 16:

ror t1, #16 + 2 ‘Where “t1” contains the contents of the memory address “command”
‘fetched with the “par” parameter.

So, this puts the “cmd” bit in bit positions 29 and 31, instead of bit positions 0 and 1. And then it gets worse.
The address of register “jumps” is added to the shifted value in t1. And then, to add insult to injury, the contents
of "t1" are shifted right two places, and then immidately shifted right again 3 places. A few steps further, the contents
of register "t2" (which were copied from t1 earlier) are shifted right by "t1" bits! Anyway, I could go on, but I won’t.
I believe that the code here is adding the value of “cmd” to the address “jumps” to look up the address o
f the “SHIFTOUT_” or “SHIFTIN_” assembly routines. Assembly code may be easy to most of you, but rememer, I
must be an idiot.

Any help understanding this would be appreciated.

Comments

  • jmgjmg Posts: 15,173
    edited 2013-01-01 11:21
    My confusion starts immediately back in the assembly routine where the bits representing “cmd” are shifted right 18 places instead of 16:

    It sounds more like confusion over Prop personality, than assembler itself.
    This example of SHR by 2, divides by 4 and is often used when a byte address is passed, but register numbers in a Prop cover 32 bits with each increment. So a /4 is applied.

    In a Prop shifting by any amount has the same cost, and memory comes in 32 bit chunks, and is precious.
    Thus you can see quite a bit of shifting to pack and unpack variables.

    On top of this, Prop code can self-modify : see MOVD/MOVS/MOVI - so larger shifts can be a sign of 'Opcode construction work'.
    Not the easiest to read, but it can be very compact.

    You could also load the code into a Prop simulator.
    For some examples, see
    http://forums.parallax.com/showthread.php?128698-Propeller-emulator
  • MagIO2MagIO2 Posts: 2,243
    edited 2013-01-01 12:13
    Just a little rephrase of what JMG already said.
                  ror     t1,#16+2                          ''lookup command COG-RAM address
                  add     t1,#jumps
                  movs    :table,t1                       ' move the jump-table address to the source part of the instruction at :table
                  rol     t1,#2                               ' get back the least significant 2 bits ( value 0-3 )
                  shl     t1,#3                              ' and multiply by 8 (bits) => result = 0 | 8 | 16 | 24
    :table        mov     t2,0
                  shr     t2,t1                               ' shift the Long to have the byte address in the least significant bytes of the long
                  and     t2,#$FF                         ' remove the rest of the long
                  jmp     t2                                ''jump to command
    jumps         byte    0                                 ''0
                  byte    SHIFTOUT_                         ''1
                  byte    SHIFTIN_                          ''2
                  byte    NotUsed_                          ''3
    

    The point here is, that the table you find at Location jumps is organized in BYTEs, whereas the the COG-RAM is organized in LONGs.
    So, if you have command 0-3 you will find them all at long-location 0. So, the confusing thing is that the code is written for a number of > 4 commands, whereas reality shows us, that there are only 2 commands at all!
    So, let's imagine we would have command number 5. The right COG-RAM location to look for it is command number / command locations per long = 5 / 4 = 1 (due to integer Division). The / 4 is the +2 in the rotation instruction. The rest of the code reads the jump-address-byte and shifts it in the way that the least significant 8 bits really hold the jump-address.

    Drawback of this method is, that the jump-addresses are stored as Bytes (8 bit) whereas the COG-RAM has 512 Longs (9 bit). So, all command entry-points HAVE to be in the first half of COG-RAM.
  • frank freedmanfrank freedman Posts: 1,983
    edited 2013-01-01 20:49
    If you are looking for some good explanations of pasm and par, there is a thread on pasm for the beginner where many of the leading personalities of these forums contributed some very good explanations and code examples on a wide range of issues including cog /hub memory access, i/o, commands like mux and many others. the thread is a vein of gold amid the accompanying slag because of all the contributions to the thread. Also check under some of the resources links for a tricks and traps document. also the potatohead papers and daSilva's tutorial.
  • 3dogpottery3dogpottery Posts: 78
    edited 2013-01-02 12:14
    Thank you jmg for your advice and the link. Thanks again MagIO2 for your detailed help. And thank you Frank Freedman for your suggestions. I see that there are many helpfull resources out there, and I will be persueing them.

    Larry
  • 3dogpottery3dogpottery Posts: 78
    edited 2013-01-02 13:05
    "Ordnung ist das halbe Leben....
    Ich lebe in der anderen H
  • frank freedmanfrank freedman Posts: 1,983
    edited 2013-01-02 13:37
    I have always liked (lived?) this one. I first came across this on the briefcase of one of my Siemens colleagues in 1987. Accurate then, accurate now..........
  • 3dogpottery3dogpottery Posts: 78
    edited 2013-01-03 08:42
    MagIO2,

    I was able to follow your detailed explanation, and I actually understand how the code works! What amazes me is that you can understand it even though it has some erroneous code in it. You are a smart man.
  • MagIO2MagIO2 Posts: 2,243
    edited 2013-01-03 11:39
    What do you mean by erroneous? The code is not optimized for this special case where you have less than 5 different commands. (It's propably extracted from another driver where more than 4 commands where needed)
    What helps a lot in understanding is experience. So, you'd better say: You are an old man ;o)
Sign In or Register to comment.