Shop OBEX P1 Docs P2 Docs Learn Events
Compilation oddity? — Parallax Forums

Compilation oddity?

Erik FriesenErik Friesen Posts: 1,071
edited 2010-04-19 03:32 in Propeller 1
I have a problem with come code here, that doesn't make too much sense to me. I can create a non working program by adding code to an unreachable location. In the attached code, adding the line - inhg:=inhgdif - below Mainscreen in PUB Start in my attached program toggles it to a nonworking program.

I believe all my stacks are sufficient size, as changing them makes no difference.

What can I look for, in a situation like this? Why would shifting the compiled output 4 bytes do something like this?

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2010-02-27 22:19
    Erik,
    This is a large, complex program. You're going to have to do a bit of work describing what it does and its structure to reasonably expect any kind of specific help with it. You've already brought up one of the possible problems, that being stack overflow. Another possibility is access to an array or via a pointer (address) that's out of range. Both would cause the type of behavior you've described. If this were my program, I'd try to isolate the portion of the program involved by using a spare I/O pin or several I/O pins to provide some kind of debug output, either using something like ViewPort or a serial LCD or even just a few LEDs. I'd insert statements to provide an indication of where the initialization routine has gotten to before "blowup". That's not always useful, but it's a start.
  • Erik FriesenErik Friesen Posts: 1,071
    edited 2010-02-27 22:24
    Yes, I know mike. Part of my problem is that I have finished doing an extensive program with a pic32 and debugger, and I guess I need to switch gears here. I am attempting to get the viewport up and running, but it doesn't want to connect.

    I don't expect folks to decipher my code, but rather I am combing for ideas on what type of things to look for.
  • BradCBradC Posts: 2,601
    edited 2010-02-28 01:07
    What constitutes "non working".

    Have you put debugging information in various bits to see where the program fails? or does it just appear to not do anything at all? Got a spare output somewhere you can connect a led to?

    You have 950 longs free as far as I can tell. Compiling with bst and optimisations turned on makes that 1232 free. I'm pretty sure in either case you are not running out of stack. There are some pretty deep calls there but nothing that should use 950 longs. All your stack for secondary cogs is allocated in VAR space anyway so it's only the main cog that might use all that stack.

    I suspect there is something more sinister going on.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    You only ever need two tools in life. If it moves and it shouldn't use Duct Tape. If it does not move and it should use WD40.
  • BradCBradC Posts: 2,601
    edited 2010-02-28 01:11
    Just a thought. You can add padding to your main routine using a String() construct. Why not place that at the end of your routine and see if the behaviour changes with the length of the padding?

    177                        inhg:=inhgdif 
    Addr : 0382:       C8 81 6C  : Memory Op Long VBASE + READ Address = 016C
    Addr : 0385:       C9 81 68  : Memory Op Long VBASE + WRITE Address = 0168
    
    



    Your construct there adds 6 bytes to the end of the routine. A basic String() with one character in it will give you 2 bytes of padding, and you can stretch it out from there to see what happens.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    You only ever need two tools in life. If it moves and it shouldn't use Duct Tape. If it does not move and it should use WD40.
  • RaymanRayman Posts: 14,887
    edited 2010-02-28 01:15
    Well, I took a 10-second look and saw this:
    byte    data[noparse][[/noparse]1029]
    byte    cols,col,rows,row,size,color,move
    long    flag,position,shiftdn,shiftrt,height,contrast,off
    PUB Start(CS1,RST,RS,RW,ENA,d0,d7) 'for no backlight use $FF. For CS1 or RW tied to ground use $FF
      waitcnt(5_000_000+cnt)'Wait for screen to stabilize
      contrast:=25
      long[noparse][[/noparse]@data]:=@SL       'send address pointers  
    

    Because I just had to debug my own issue, I get a little nervous about defining things as "bytes" in the var section (like data[noparse][[/noparse]1029])

    and then addressing them as long (like long[noparse][[/noparse]@data]).

    Now, you may not have the same trouble as me, but I find that it's much less risky to define everything as longs, even if you intend to
    address them as bytes.· Especially, if you intend to give the address to an assembly cog...

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    My Prop Info&Apps: ·http://www.rayslogic.com/propeller/propeller.htm

    My Prop Products:· http://www.rayslogic.com/Propeller/Products/Products.htm
  • BradCBradC Posts: 2,601
    edited 2010-02-28 01:18
    Well, that would work 1/4 of the time depending on alignment. Nice catch!

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    You only ever need two tools in life. If it moves and it shouldn't use Duct Tape. If it does not move and it should use WD40.
  • Erik FriesenErik Friesen Posts: 1,071
    edited 2010-02-28 01:31
    The definition of "non working" varies. The LCD won't fire up, my encoder may not work, or my fram reads wrong depending on where we are at.

    I have a niggling suspicion that it is in my lcd code however.

    I was under the impression that the compiler arranged it in this order - All longs first, then words, with the first aligned on a long boundary, then bytes, with the first on a long boundary.(within each object) I may be wrong on this point, which could be my problem.
  • BradCBradC Posts: 2,601
    edited 2010-02-28 11:54
    Erik Friesen said...

    I was under the impression that the compiler arranged it in this order - All longs first, then words, with the first aligned on a long boundary, then bytes, with the first on a long boundary.(within each object) I may be wrong on this point, which could be my problem.

    Yeah, I'm afraid you are quite wrong. The reason for packing them the way it does is so there are no alignment requirements for the start of words or bytes.

    You can guarantee a long is always on a long boundary. Likewise, the first word is always aligned on a long boundary (as it follows the longs) and the first byte is always on a word boundary.

    Now, having said that, in your ALLV203.spin you have no word allocations, so your byte will always start on a long boundary (and it does)

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    You only ever need two tools in life. If it moves and it shouldn't use Duct Tape. If it does not move and it should use WD40.
  • Erik FriesenErik Friesen Posts: 1,071
    edited 2010-04-19 02:15
    It appears that this problem may have been related to a missing #. Can anyone provide me an explanation on why this code has worked at all? Or why byte alignment could affect this? This is on line 854 of s6b0724small.

    if_z jmp printchar_ret

    ....

    printchar_ret ret
  • Mike GreenMike Green Posts: 23,101
    edited 2010-04-19 02:23
    Yes, you surely have to have a "#" in front of the address in the JMP. The "#" turns on the immediate operand bit of the instruction. Any kind of jump address normally has to be an immediate operand since the source field value is copied to the program counter. There are some cases where you'd not use a "#", but they're unusual, like if you're computing a jump address or taking it from a table or other variable.
  • kuronekokuroneko Posts: 3,623
    edited 2010-04-19 02:38
    Erik Friesen said...
    It appears that this problem may have been related to a missing #. Can anyone provide me an explanation on why this code has worked at all? Or why byte alignment could affect this? This is on line 854 of s6b0724small.

    if_z jmp printchar_ret

    ....

    printchar_ret ret
    I'd argue that this isn't the reason for your problem(s). Whether you use a # here or not doesn't matter. If you use it then you jump to the ret and then back to the caller. If you don't use it then you simply jump directly back to the caller. (the printchar subroutine has been called, which means that the source field of printchar_ret is setup with the return address so a jmp reg just works).
  • Cluso99Cluso99 Posts: 18,069
    edited 2010-04-19 03:32
    kuroneko is correct. It does not matter in this instance. In fact, without the "#" is faster, one instruction fatster.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Links to other interesting threads:

    · Home of the MultiBladeProps: TriBlade,·RamBlade,·SixBlade, website
    · Single Board Computer:·3 Propeller ICs·and a·TriBladeProp board (ZiCog Z80 Emulator)
    · Prop Tools under Development or Completed (Index)
    · Emulators: CPUs Z80 etc; Micros Altair etc;· Terminals·VT100 etc; (Index) ZiCog (Z80) , MoCog (6809)·
    · Prop OS: SphinxOS·, PropDos , PropCmd··· Search the Propeller forums·(uses advanced Google search)
    My cruising website is: ·www.bluemagic.biz·· MultiBlade Props: www.cluso.bluemagic.biz
Sign In or Register to comment.