Shop OBEX P1 Docs P2 Docs Learn Events
Passing parameters wih assembly — Parallax Forums

Passing parameters wih assembly

LuckyLucky Posts: 98
edited 2010-04-14 19:42 in Propeller 1
Trying to get started in the assembly programing for the prop and I am having a hard time understanding·passing parameters from spin to assembly. I have already looked at the examples in the assembly examples sticky note but they are not helping. Can someone write a short demo to·demonstrate the passing of two parameters to assembly routine, the assembly routine adding two to each parameter and then·passing the values back to spin and using the FulDuplexSerial object to print out the two·parameters.·(is there a certain offset value that you add to the par register to know the locaion of the second parameter?)
······························································································································ -Thanks



▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"The man who smiles when things go wrong has thought of someone to blame it on."


-Lucky[size=-1][/size]

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2010-04-12 22:43
    The PAR register provides a long aligned address (a multiple of 4). The least significant 2 bits are always zeroed no matter what you provide to the COGNEW or COGINIT. What offset you use to get the "next" parameter depends on what parameters you're using. If you have two longs, the offset is 4. If you have two words, the offset is 2. If you have two bytes, the offset is 1. How about if you provide an example based on what you understand and we'll clarify anything that needs it? What don't you understand about the examples in the sticky notes? You're the one who's trying to learn. The practice will be good for you.
  • LuckyLucky Posts: 98
    edited 2010-04-12 23:16
    CON
    ·· _clkmode = xtal1 + pll16x
    ·· _xinfreq = 5_000_000

    VAR
    ·· Long Num, Num2
    ··
    OBJ
    ·· debug : "FullDuplexSerial"

    PUB Main

    ·· Debug.start(31, 30, 0, 115200)
    ·· waitcnt(clkfreq*5 + cnt)
    ·· Num := 20
    ·· Num2 := 22
    ·· AddTwo(Num, Num2)
    ····
    PUB AddTwo(_num,_num2): Flag

    ··· cognew(@entry, @_num)
    ··· repeat while Flag == 0
    ······ debug.dec(_num)
    ······ debug.dec(_num2)

    DAT
    ······················· org
    entry
    ······················· mov···· _Flag,·· par······ ' Move argument address into _Flag
    ······················· add···· _Flag,·· #8······· ' Point to 3rd argument "_Flag"
    ······················
    ······················· wrlong· Zero, _Flag······· ' Clear 'Flag before we start'
    ·······················
    ······················· add···· _num, #2········· ' Add 2 to _num
    ······················· add···· _num2, #2········ ' Add 2 to _num2
    ······················· wrlong· _num, par········ ' Return result to _num
    ······················· wrlong· _num2, par······· ' Return result to _num2

    ······················· wrlong· One, _Flag··········· ' Set 'Flag when we are done'

    CogNum················· long··· 0
    Zero··················· long··· 0
    One···················· long··· 1
    _Flag·················· res···· 1

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    "The man who smiles when things go wrong has thought of someone to blame it on."


    -Lucky[size=-1][/size]
  • Mike GreenMike Green Posts: 23,101
    edited 2010-04-12 23:34
    Your main problem is that there isn't a 3rd argument.· Specifically, "Flag" does not follow "_num" and "_num2", so you can't pass the address of "_num" and expect that the result parameter is 8 bytes beyond that.

    As you may have noticed, "_num" and "_num2" don't exist as far as the assembly language is concerned.

    Remember that the only instructions that can access hub memory where all Spin variables are kept are RDxxxx and WRxxxx.· All other instructions like MOV and ADD can only access cog memory.· Any data held in Spin variables has to be copied to cog locations, manipulated, then copied back to hub memory.

    It doesn't work to write "ADD _num,#2".· If you have the address of "_num" in PAR, you could write "RDLONG temp,PAR", "ADD temp,#2", "WRLONG temp,PAR".
  • LuckyLucky Posts: 98
    edited 2010-04-13 01:39
    Well it seems the next logical question would be how does one correctly go about retrieving the address of the 1st parameter, 2nd parameter, etc., so I can use the steps you have mentioned above?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    "The man who smiles when things go wrong has thought of someone to blame it on."


    -Lucky[size=-1][/size]
  • kuronekokuroneko Posts: 3,623
    edited 2010-04-13 02:02
    Lucky said...
    Well it seems the next logical question would be how does one correctly go about retrieving the address of the 1st parameter, 2nd parameter, etc., so I can use the steps you have mentioned above?
    FWIW, the variable order seems to be like this: result followed by method parameters (left to right) followed by local variables. So in your case passing the address of Flag should allow you to access all the other locations (by repeatedly adding 4, i.e. indexed access).

    Note that all accesses must be based on par, you can't use SPIN names down there [noparse];)[/noparse]

    Post Edited (kuroneko) : 4/13/2010 2:08:07 AM GMT
  • LuckyLucky Posts: 98
    edited 2010-04-14 01:31
    Is this a step in the right direction? It worked when I ran it. Is there a more efficient way to complete the same task? It takes 25 longs of RAM when done in assembly and only 9 when coded in spin only. Do the advantages of assembly only come with larger programs?

    __________________________________________________________________________________________________________________________

    CON

    ·· _clkmode = xtal1 + pll16x
    ·· _xinfreq = 5_000_000

    VAR

    ·· long num, num2, flag

    ·
    OBJ

    ·· debug : "FullDuplexSerial"

    PUB Main

    ·· Debug.start(31, 30, 0, 115200)
    ·· waitcnt(clkfreq*5 + cnt)
    ·· num := 2
    ·· num2 := 4

    ·· cognew(@entry, @num)
    ···
    ·· repeat while Flag == 0
    ·· debug.dec(num)
    ·· debug.dec(num2)

    DAT
    ······················· org
    entry
    ······················· mov···· mem,·· par
    ·······················
    ······················· mov···· _Flag, par
    ······················· add···· _Flag, #8
    ······················· wrlong· Zero, _Flag
    ·······················
    ······················· call #addition
    ······················· add·· mem, #4
    ······················· call #addition

    ······················· wrlong· One, _Flag··········

    ······················· CogID CogNum
    ······················· CogStop CogNum

    addition··············· rdlong· _num, mem
    ························ ·add···· _num, #2
    ························ ·wrlong· _num,mem
    addition_ret·········· ret······

    Zero···· ·long·· 0
    One······ long·· 1
    CogNum· res··· 1
    mem······ res··· 1
    _Flag····· res··· 1
    _num····· res··· 1

    __________________________________________________________________________________________________________________________

    output on debug terminal is "46"



    ··················

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    "The man who smiles when things go wrong has thought of someone to blame it on."


    -Lucky[size=-1][/size]
  • Mike GreenMike Green Posts: 23,101
    edited 2010-04-14 01:35
    Assembly really only has advantages for raw speed and precise timing. It always takes more space than Spin code.
  • LuckyLucky Posts: 98
    edited 2010-04-14 01:47
    @kuruneko: I think your wrong, I just ran a modified version of the program and the variable order worked as method parameters FOLLOWED by the result variable

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    "The man who smiles when things go wrong has thought of someone to blame it on."


    -Lucky[size=-1][/size]
  • kuronekokuroneko Posts: 3,623
    edited 2010-04-14 02:03
    Lucky said...
    @kuroneko: I think your wrong, I just ran a modified version of the program and the variable order worked as method parameters FOLLOWED by the result variable
    You are just ... erm ... lucky. Your program is corrupting stack space which has the side effect that your repeat loop terminates. If you add a local variable the loop will just sit there forever. Then change your PASM code to sub _Flag, #4 and it starts working properly.

    If you still don't believe me just display the addresses of the variables:

    debug.hex(@_num, 8)
    debug.tx(13)
      
    debug.hex(@_num2, 8)
    debug.tx(13)
    
    debug.hex(@flag, 8)
    debug.tx(13)
    
  • JonnyMacJonnyMac Posts: 9,392
    edited 2010-04-14 15:57
    @Lucky,

    You may find the attached demos helpful. The first is an update of what you're doing. As you've no-doubt figured out, using PASM for simple math is a waste of energy. That said, the command interface is useful for more advanced processes. For example, I've attached my 1-Wire object which uses the same parameter passing mechanism. In this case, you can't do 1-Wire in Spin so the connection to PASM for time-critical processes is useful.

    Sorry... I was forced to change the extension on the files to .txt so the forum software would allow the upload -- have no idea why....

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon McPhalen
    Hollywood, CA
  • potatoheadpotatohead Posts: 10,261
    edited 2010-04-14 17:40
    I have that same problem with uploads.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Propeller Wiki: Share the coolness!
    8x8 color 80 Column NTSC Text Object
    Safety Tip: Life is as good as YOU think it is!
  • LuckyLucky Posts: 98
    edited 2010-04-14 19:42
    Thank you JonnyMac, those examples were very helpful

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    "The man who smiles when things go wrong has thought of someone to blame it on."


    -Lucky[size=-1][/size]
Sign In or Register to comment.