Locating functions in memory

  • diamondmind

    diamondmind - 2008-02-28

    Is there a way to place functions / subroutines at specific address(es) in memory? I have a function, myFunc(), and I'd like to tell the compiler to locate it at a specific address in memory. When I try it with variables ...

    ie: __code __at (0x1000) char var = 0x20;

    ... it works, but when I tried it with functions ...

    ie: __xdata __at (0x1200) void myFunc(void);

    ... the compiler gives no errors or warnings, but the *.lst file still has it at the same address as a normal function declaration.

    What I'm ultimately trying to come up with is a quick and dirty hack for autovectoring on a Cypress FX2 devel board and I can do everything except place a function at a specific memory location.

    • Maarten Brock

      Maarten Brock - 2008-02-28

      I think you will need assembly to get this working.

    • Steven

      Steven - 2008-02-28


      Have a look at the #pragma codesec

      e.g. Untested.
      File myFunc.c

      #pragma codeseg myFunc
      void MyFunc(void) {


      and then

      sdcc test.c -wl -bmyFunc=0x2000

      Good luck,


      • Steven

        Steven - 2008-02-28

        BTW, there is also a command line argument you can use instead of the pragma.

        I think it's --codeseg.


    • diamondmind

      diamondmind - 2008-03-01

      Hmm ... my version of SDCC (2.7.0) didn't like the -w or -b switches. I've split my code up into separate files (one for the main function and the other containing the function I'm trying to locate) and put:

      #pragma codeseg FUNC_NAME

      at the top of the file containing the function. SDCC will compile that file just fine ($ sdcc -c funcFile.c) and I get the *.rel and other files. I can then link them with the main file ($ sdcc -I ./include -mmcs51 main.c funcFile.rel) which gives me a working *.ihx file I can send to the board.

      I found this in the SDCC manual (Section 3.2.9):

      --codeseg <Name> The name to be used for the code segment, default CSEG. This is useful if you need to tell the
                 compiler to put the code in a special segment so you can later on tell the linker to put this segment in
                 a special place in memory. Can be used for instance when using bank switching to put the code in a

      But I'm not exactly sure how to use it to locate <Name> (ie FUNC_NAME in my case) at a specific location (ie 0x1200).

        $ sdcc -I ./include -mmcs51 main.c funcFile.rel --codeseg=0x1200 FUNC_NAME

        sdcc -I ./include -mmcs51 main.c funcName.rel --codeseg=0x1200 FUNC_NAME
        at 1: warning 117: unknown compiler option '--codeseg=0x1200' ignored
        at 1: warning 119: don't know what to do with file 'FUNC_NAME'. file extension unsupported

        $ sdcc -I ./include -mmcs51 main.c funcFile.rel --codeseg FUNC_NAME=0x1200

        sdcc -I ./include -mmcs51 main.c funcFile.rel --codeseg FUNC_NAME=0x1200
        ?ASxxxx-Error-<q> in line 668 of main.asm
                    <q> missing or improper operators, terminators, or delimiters

      I'm obviously missing something the manual is saying. Do you use the #pgragma with the --codeseg or separately? Your previous post implies separately but the manual seems to say you use them together?

      I really appreciate all the help so far. At least I'm on the right track .. hopefully. ^_^


      • Anonymous - 2008-03-02


        I don't know about creating new segments at explicit locations.

        However i used the sdcc, and the correct syntax for changing the start of the code is:

        --code-loc 0x0200 --code-size 0x1200

      • Maarten Brock

        Maarten Brock - 2008-03-03

        You should either use #pragma codeseg MY_SEG or --codeseg MY_SEG but not both. To give this segment an address you use -Wl,-bMYSEG=0x1200. That is with a comma after the 'l'. It seems this comma is lost in the manual.


    • diamondmind

      diamondmind - 2008-03-03

      I think that's what is causing my confusion. All of the facilities described in the manual are for locating *all* the program code at another location in memory (or am I not understanding?). I'm trying to figure out how to locate one particular *function* at a non-default address while leaving the rest at the default locations. When I move the entire program around, the ISRs are no longer located where the hardware expects (among other problems) which is the main problem I'm trying to solve to begin with. I'll keep digging and see what I can find. Thanks again for all the help! :)

      • Anonymous - 2008-03-03

        Well, some hardware locations are fixed. I don't know how to do it in SDCC c programs, but in asm I located my vectors:

        * note: ljmp takes 3 bytes, the vectors must be 8 byte aligned

              .area interrupt_area(ABS)

              .globl __sdcc_gsinit_startup

               * Where the CPU starts execution on a cpu reset
              .org 0x0000 
              ljmp   __sdcc_gsinit_startup ; Jump to C entry point

               *  External INT 0 starts at location 3
              ljmp hang
               * unexpected isr -- tuck in a hang here - should not happen
        hang: ljmp hang   
              .db 0x00, 0x00

               * Timer 0 - There seems to be a hardware bug, timer 0 crashes
              ljmp _fx2isrTimer

               * External INT 1
               * Hardware requires it to be at .org 0x13
              ljmp hang
              .db 0x00, 0x00, 0x00, 0x00, 0x00

        Note depending on your cpu flavor, there may be many more vectors. You can  either pad each vector to 8 bytes or use more .org statements.

        I would look at some sdcc sample code. It probably does the same in C.

        Regards, Steve


Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:

JavaScript is required for this form.

No, thanks