Still struggling to understand Assembly
3dogpottery
Posts: 78
In an attempt to understand Assembly, Ive 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 wont.
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.
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 wont.
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
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
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.
Larry
Ich lebe in der anderen H
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.
What helps a lot in understanding is experience. So, you'd better say: You are an old man ;o)