Wednesday, May 27, 2015

Functions and Stack



                       ###########                                                           ######## 
                       # Registers #                                                           #  Stack #
                       ###########                                                           ########
###################################        ####################################
####            Stack Pointer (sp)                ###       ###                local variable n                    ###
###################################        ####################################
####              Fame Counter (fc)             ###       ###                .........................                    ###
###################################        ####################################
####            Link Register (lr)                ###       ###                 local variable 1                  ###
###################################        ####################################
####           Program Counter (pc)          ###       ###             Passed Parameter n                ###
###################################        ####################################
                                                                              ###             ...............................                ###
                                                                              ####################################
                                                                              ###             Passed Parameter 1                ###
                                                                              ####################################
                                                                              ###    caller function lr (return address)   ###
                                                                              ####################################
                                                                              ###  caller function fp (frame pointer)     ###
                                                                              ####################################
                                                                              ###              same block repeats              ###
                                                                              ###              for caller functions              ###
                                                                              ###              ................................              ###
  • Stack pointer (sp) register:
    • Is a HW register, which points to the top of the stack
    • As local variables are defined, they are added to the stack, and the stack pointer value changes.
    • Since the stack pointer is changing, we can not reference the function parameters and local variables as offset from the sp value
    • Instead, we reference the function parameters and variables by adding offset to the frame pointer (fp)
  • Frame Pointer (fp) register
    • Frame pointer register, points to the bottom of the stack part that is related to the current function
    • By other words, fp = sp, before adding the function parameters or local variables.
    • fp value is constant for a function, hence it is used to reference the function parameters and local variable.
  • Program Counter (pc) register:
    • A register that points to the next instruction to be executed.
  • Link Register (lr):
    • When calling a function, a branch happens from the normal sequence to the address of this function.
    • The return address is saved in the link register.
    • After the function finishes, pc = lr
  • When a function call happens:
    • Current lr is saved to stack --> Update sp
    • lr = pc + 1 (return address is saved to lr)
    • Current fp is saved to stack --> Update sp
    • Current sp is saved to fp
    • Parameters are moved to stack --> Update sp
    • Local variables are created on stack --> Update sp
    • Parameters and local variables are refered to as [fp + offset]
    • After the function is finished:
      • It returns the return value in a special register
      • sp = fp
      • pc = lr
      • fp = saved fp
      • lr = saved lr



Sunday, May 24, 2015

Embedded C Build Process


  • Pre-Processor:
    • .c + .h --> .i
    • .c + .h --> .i
    • .c + .h --> .i
    • Stripes out the comments
    • Substitute the #include
    • Substitute the # macros
  • Compiler:
    • .i --> .s --> .o
    • .i --> .s --> .o
    • .i --> .s --> .o
    • from c to assembly
    • the assembly is written in machine code
    • each .o file contains:
      • symbol table
        • symbol name | address in memory | symbol size | symbol section (bss - data - rodata - text - ...etc)
        • all addresses are relative to the file
        • for external variables, the addresses are not determined. (to be determined after linking)
      • sections
        • bss: uninitialized global variables
        • data: initialized global variables
        • rodata: constants
        • text: code
  • Linker:
    • .o + .o + .o + startup.o + standard_libs.o --> app.o
    • standard_libs.o
      • to resolve functions like printf(), ...etc
    • startup.o
      • disable all interrupts
      • copy initialized variables from ROM to RAM
      • initialize uninitialized data
      • allocate space for stack and initialize it
      • initializes the processor stack pointer
      • create and initialize the heap
      • enable interrupts
      • call main
      • startup is written by the developer as assembly or c, then compiled and linked with the application
      • When the reset line is disabled (once the processor start working), the program counter points to the start up
      • "Start up" can be called "boot loader", usually it is called a boot loader if it comes more complicated than just doing the above points.
        A "boot loader" can load OS, initialize HW, ...etc.
        If a boorloader is interupted "by a push button, or an escape method, ...etc", it stops loading the main program, and wait for a new main program to be flashed ...etc.
    • app.o:
      • all text, bss, data, rodata sections of all the input object files are merged together, hence:
        • symbol table contains zero unresolved symbols
        • bss contains all uninitialized variables
        • data contains all initialized variables
        • rodata contains all constants
        • text contains all code
      • In case of embedded systems: 
        • the addresses needs to be mapped to the system memory
        • this is done using a "linker script" in the "locating" process
  • Locator:
    • app.o + linker script --> targetFile
    • To be continued



You can use the files in the this link, a long with the following commands to see the above info in action:
// to run preprocessor-compiler-linker-locator, saving all temp file
gcc main.c add.c -o adder -save-temps
// you can view the preprocessor output
*.i
// you can view the assembly
*.s
// to view the object files, and target file:
objdump -d -t -s adder > adderObjectDump
objdump -d -t -s main.o > mainObjectDump
objdump -d -t -s add.o > addObjectDump

    where:  -d // display the executable sections in assembly form (disassemble)
                 -t // print symbol table
                 -s // display the contents of the sections