Showing posts with label C++. Show all posts
Showing posts with label C++. Show all posts

Tuesday, September 18, 2018

Choose your programming language

C++, Java, C#, Objective C. First we see the differences, hence we can make decisions.

For each language we will try to answer two questions:

  • Performance?
  • Binaries are portable or not.
C++:
  • It is compiled to be executed directly on the machine. That means each machine shall run binaries compiled specifically for it.
  • Hence, the binaries are not portable. And for the same reason, the performance is better.
  • Performance:  😌
  • Portability:     😞
Java, C# and Objective C:
  • Java is compiled to be run on JVM, not to be run directly on the target machine. Hence, the binaries can run on any target, as long as the JVM is installed. For the same reason the performance is less than C++ programs.
  • JVM is available for Windows, Linux and Apple.
  • C# is the same to say like in Java. With the following analogy
    • JVM :: .NET CLR (Common Language Runtime)
    • .NET framework including CLR is primarily supported for windows
      • People may have ported .NET framework to other OSes. But mainly .NET framework is for windows
  • Objective C:
    • Same concept as C#, with the following analogy:
      • .NET CLR :: Othe VM
      • Windows :: Apple OS X
  • Performance:  😞
  • Portability:
    • Java             😌
    • C#                😌 for windows
    • Objective C 😌 for Apple OS X
Also, Java, C# and Objective C giving errors like outofbound and so on, they prevent and diagnose such hard debugging problems. C++ does not do this. Of course this will add overhead to the execution and will degrade performance.

Now we can make decisions:
  • C: use it for small, low level, low sized target codes (Ex: device driver of embedded system).
  • C++, Java, C# Objective C: use it for larger code, for better modularity than C, with reasonable performance degradation.
    • C++: to get the maximum performance of a machine, ex: games, graphics apps that requires high performance.
    • Java: Do not need that high performance? Want to be platform independent and reach all users without installers? Go Java (For all OSes), C#(For windows apps) or Objective C(for Apple OS X apps).

Sunday, January 3, 2016

ARM Development Suite



In this post, I will make a guide, on how you can set up development environment for embedded C programming.

In order to be able to write an embedded C program, and execute it, you need four things:

  1. An IDE, from which you can write the code, navigate through it, perform compilation, debugging, ..etc
  2. The tool chain (Compiler - Linker - Debugger)
  3. In circuit debugger, if you will download this to your real target. If not, you can use a simulator.
  4. The target.
In the following lines, I will illustrate how could I got each of these things

The Target:

I am using STM32F103DEV development Kit.


Microcontroller is, ARM Cortex M3 Family Micro-controller, namely: STM32F103. From ST Microelectronics.











In circuit debugger:


I am using ARM-USB-TINY-H from Olimex,
It is a JTAG debugger supported by OpenOCD (Open On-Chip Debugger). OpenOCD is open source software supporting JTAG debuggers for different Targets.

OpenOCD license is GNU GPL (GNU General Public License)

How to install OpenOCD for ARM-USB-TINY-H?

  Host machine:
  • Connect your ARM-USB-TINY-H Debugger to the machine
  • Download Zadig, Open it, Choose your device (Interface 0), Choose WinUSB > Install

  • In  ARM-USB-TINY-H page, download "OpenOCD for windows".
  • Extract it to any local directory.
  • Make a batch file, write the following in it:
@echo
cd <extract-path>\openocd-0.9.0-rc1\bin
openocd.exe -f ../scripts/interface/ftdi/olimex-arm-usb-tiny-h.cfg -f ../scripts/target/stm32f1x.cfg
@echo
  • To start debugging, Run the batch.
  Client machine:
  • From any other machine, you can configure your IDE to use GDBServer, and provide the IP of the host. 
  • You can use the same host machine as client, in this case the IP will be the localhost with port number 3333 (localhost,3333)


The IDE, and the Tool Chain

I will demonstrate three (free) alternatives:
  1. IDE: IAR IDE with Tool chain: IAR (Free version limited code size)
  2. IDE: Eclipse   with Tool chain: IAR (Free version limited code size)
  3. IDE: Eclipse   with Tool chain: GNU
1. IDE: IAR IDE  with Tool chain: IAR (Free version limited code size)
  • Just go to IAR site, download EWARM (Embedded Workbench for ARM) installer, run it.  It is a normal installation.
  • After installation, when you first open the IDE, it will ask you for a license if you have.
  • If you do not have a license, click "register", you will be asked if you want a free license with limited time, or limited code size, choose what you prefer.
  • Now, you successfully downloaded:
    • IAR IDE
    • IAR Compiler for ARM
    • IAR Linker for ARM
    • IAR Debugger for ARM
2. IDE: Eclipse  with Tool chain: IAR (Free version limited code size)
  • Tool chain: please refer to point 1
  • IDE: Eclipse and Eclipse IAR plugin
    • Install Eclipse
      • From Eclipse web site. You will need to download and install eclipse Indigo or newer. (I installed Mars)
        • Each eclipse version requires a minimum version of Java Runtime Environment.
        • When installing Eclipse, the installer will detect automatically if you need a newer version of JRE, and will direct you to Oracle website to download and install it.
        • Finish installing Eclipse
    • Install Eclipse IAR Plugin
      • Launch Eclipse
      • Help > Install New Software
      • There is a guide on IAR website, for eclipse plugin installation. Please follow it to complete the installation.
Now you can create a project that uses IAR tool chain:
  • Click on menu: File > New > C Project















  • Choose Executable (IAR) > Project with empty main()
  • Finish























To Choose your target device:
  • Project > Select Device
  • Browse > select a device (In my case I select ST > STM32F103x6)
For Debugging:
  • Select the project
  • Run menu > Debug Configuration
  • On the left tree, expand C/C++ Application, and select your project (If you did not find your project, make a "New launch configuration" from the up left button)
  • By default, GDB is used, Click "Select Other", choose "IAR C-SPY Debugger for ARM Launcher" > OK

  • From Setup Tab
    • Simulator, if you want to use the simulator
    • The debugger you are using to download and debug on target


Unfortunately, I was not able to find GDB server within the available drivers, although it exists in IAR IDE! This means, that in this case, we will be able only to use the simulator.


3. IDE: Eclipse  with Tool chain: GNU
  • Install GNU Tools for ARM
    • From launchpad downloads page
    • Download and install
    • At the installation end, choose to add registry stuff, and to add the path to the path environment variable
  • Download windows build tools (make):
    • Go to source-forge arena
    • Download the most recent file of gnuarmeclipse-build-tools-win32-2.*-*-setup.exe
    • Install
  • Install the GNU ARM plugins to eclipse
    • Open eclipse > Help > Install new SW > Add
      • Name: GNU ARM Eclipse Plug-ins
      • URL: http://gnuarmeclipse.sourceforge.net/updates
      • Press OK, and continue installation


  • Create a new C project
    • From Eclipse: File > New > C Project
      • Executable > STM32F10x C/C++ Project > Cross ARM GCC
      • Fill in the Project name



      • Next > Next > Next > Next
      • Add GNU Tools for ARM installation path.
      • Finish


  • Select the project > Project > Properties > C/C++ Build > Set the build path and the tool chain path

For Debugging:
  • Window > Preferences

  • Select the project > Run > Debug Configuration
  • Please follow the screenshots to build a debug configuration





  • Press debug

Summary:

We discussed three configurations:

Configuration 1:

------------------------------------------------------------------------------------
                                             IAR IDE
------------------------------------------------------------------------------------
                                        C-SPY Debugger
------------------------------------------------------------------------------------
Instruction Set Simulator | C-SPY Debugger OpenOCD Server Driver
------------------------------------------------------------------------------------
                                         | Ethernet
                                        ------------------------------------------------------
                                         | OpenOCD driver for ARM-USB-TINY-H
                                        ------------------------------------------------------
                                         | ARM-USB-TINY-H JTAG
                                        ------------------------------------------------------
                                         | TARGET
                                        ------------------------------------------------------


Configuration 2:

------------------------------------------------------------------------------------
                                    Eclipse with IAR Plugin
------------------------------------------------------------------------------------
                                        C-SPY Debugger
------------------------------------------------------------------------------------
Instruction Set Simulator | C-SPY Debugger OpenOCD Server Driver
------------------------------------------------------------------------------------
                                         | Ethernet
                                        ------------------------------------------------------
                                         | OpenOCD driver for ARM-USB-TINY-H
                                        ------------------------------------------------------
                                         | ARM-USB-TINY-H JTAG
                                        ------------------------------------------------------
                                         | TARGET
                                        ------------------------------------------------------

Configuration 3:

------------------------------------------------------------------------------------
                               Eclipse with GNU ARM plugin
------------------------------------------------------------------------------------
                                        GNU Debugger
------------------------------------------------------------------------------------
                              GNU Client OpenOCD driver
------------------------------------------------------------------------------------
                                              Ethernet
------------------------------------------------------------------------------------
                      OpenOCD driver for ARM-USB-TINY-H
------------------------------------------------------------------------------------
                                ARM-USB-TINY-H JTAG
------------------------------------------------------------------------------------
                                          TARGET
------------------------------------------------------------------------------------

Wednesday, September 23, 2015

Create/Build C Project in VS C++

How To Create C Project in VS C++?
To edit your C program:
  1. From the main menu select File -> New -> Project
  2. In the New Project window:
    Under Project types, General > Empty Project
    Name your project, and specify a location for your project directory
    Click 'OK', then 'next'
  3. In the Application Wizard:
    Select Console application
    Select Empty project
    Deselect Precompiled header
  4. Once the project has been created, in the window on the left hand side you should see three folders:
    Header Files
    Resource Files
    Source Files
  5. Right-click on Source Files and Select Add-> New Item
    Select Code, and give the file a name
    The default here will be a file with a *.cpp extension (for a C++ file). After creating the file, rename it as a *.c file.
To compile and run:

  1. Press the green play button.
  2. By default, you will be running in debug mode and it will run your code and bring up the command window.
    To prevent the command window from closing as soon as the program finishes execution, add the following line to the end of your main function:
    getchar(); 
    This library function waits for any input key, and will therefore keep your console window open until a key is pressed.
  3. Another alternative is to use: 
    Or debug > Start without debuging
Precompiled Headers
Precompiled headers are a mechanism to speed up compilation by creating a partially processed version of some header files, and then using that version during compilations rather than repeatedly parsing the original headers.

Resource Files in VSC++
There are 3 folders in the “Solution Explorer Window” in VSC++:
·         Header Files: (.h)
·         Source Files: (.c)
·         Resource Files: (exe-images-...etc)

Win32 Vs Win64
·         Win32 has 32-bit address line à can support up to 4 GBytes RAM
·         Win64 has 64-bit address line à can support larger size RAM
·         Win32 Application shall run on both Win32 and Win64 system
·         Win64 Application shall run only on Win64 system

Assuming that we use Win64 machine for development, and we want the program to run on Win32 machines:
Host Platform: Win64 – Intel Processor
Target Platform: Win32/64 – Intel Processor

Notes:

  • Some compiler fires a warning in case of using undefined function. And assumes it is externed.
  • If the linker did not find the function externed, then it will fire an error
  • The manifest is not important for c, you can run the exe directly
  • Generated exe file is not pure machine code? it is OS dependent!

Sunday, September 20, 2015

Memory

Memory Types:


  • RAM
    • Data memory
    • Volatile
    • Fast
  • EEPROM / Flash
    • Program memory
    • Nonvolatile
    • From Wikipedia
    • Slow
  • Virtual memory
    • The OS combines regions of the RAM + regions of the Hard disk, and provide virtual addressing for them as if they are contiguous, to be used as a RAM
    • Have larger RAM, but slower
  • Cache memory
    • Faster than rams
    • Data cache, contains the data that is accessed frequently
    • Program cache, contains instructions that is being executed


Memory Management
  • The OS is responsible for allocating/deallocating/moving the heap/stack of the different processes

Friday, September 4, 2015

#define macro with a return value!

Can be done in gcc:

#define IS_DIGIT(x) ({\
int l;\
if (x == 1){\
l = 1;\
}else{\
l = 0;\
}\
l;\
})

The above macro returns an integer l. Can be used as follows:

int x = IS_DIGIT(1);

switch vs if

if the cases of switch are consecutive numbers, then switch may be more optimized than if

Example:

If worst case--> 4 comparison

If (x == 1){
    body 1;
else if (x == 2){
    body 2;
else if(x == 3){
    body 3;

else if(x == 4){
    body 4;
}

Assembly:

beq x,1,L1
beq x,2,L2
beq x,3,L3
beq x,4,L4
...
...
...
L1:
Body 1

L2:
Body 2

L3:
Body 3

L4:
Body 4




switch worst case --> 1 comparison

switch (x){
    case 1: 
        body1;
        break;
    case 2: 
        body2;
        break;    case 3: 
        body3;
        break;    case 4: 
        body4;
        break;}

Assembly:

jumpIfLessThan x,4,switch+x-1
...
...
...
switch:
    L1
    L2
    L3
    L4

...
...
...
L1:
Body 1

L2:
Body 2

L3:
Body 3

L4:
Body 4


Modern compilers output the same assembly for both switch and if

Wednesday, August 12, 2015

Structures

While reading in the book "The complete C Reference". I got some notes!


Structures, Unions and Enumerations are declared/defined similar to each other

  • struct tag{   type member_name;
       type member_name;   type member_name;
    } variable_list;
  • union tag{   type member_name;
       type member_name;   type member_name;
    } variable_list;
  • Enumeration tag{   enumeration list
    } variable_list;
Where, tag is optional, variable list is optional, but at least one of them must exist

  • For bit fields, the bits runs from left to right or from right to left dependent on the machine
  • typedef syntax:
    typedef type_name new_name;

Wednesday, August 5, 2015

Expressions

While reading in the book "The complete C Reference". I got some notes!

Expressions

  • DataTypes:
    • char: 1 byte
    • int
    • float
    • double
    • void
  • Modifiers:
    • signed
    • unsigned
    • long 
    • short
  • DataTypes with modifiers (some notes)
    • the default is "signed"
      Ex:
      • char = signed char
    • Sizes:
      • char: 8 bits
      • short int: 16 bits
      • long int: 32 bits
      • long long int: 64 bits (added by C99)
      • float: 32 bits
      • double: 64 bits 
      • long double: 80 bits (added by C99)
  • Identifiers (variable and functions names, labels, ...etc) :
    • first character: "_" or a letter
    • other characters: "_" or letter or number
    • significant charachters:
      • internal identifiers (used only in the same file)
      • external identifiers (used in more than one file, like global variables and functions)
      • C89:
        • for internal identifiers: 31 characters are significant
        • for external identifiers: 6 characters are significant ("studentName" and "studentNameCon" will be treated as the same identifier!)
      • C99:
        • for internal identifiers: 63 characters are significant
        • for external identifiers: 31 characters are significant
  • Variables
    • C89: all variables shall be declared in the beginning of the block
    • C99: can be defined anyway
  • 4 C Scopes:
    • File Scope (variables defined in file scope are global)
    • Block Scope (variables defined in a block scope, are local to there block, also variables defined in the function definition (formal parameters) are local to the function block scope )
    • Prototype Scope (variables declared in function prototype, are local to the prototype)
    • Function Scope: applies only to the labels. (so block scope does not apply to labels, function scope is applied instead!)
      • the following code is not valid
        void func1(){
         
        fun1: goto fun2;
        }
        void fun2(){
         
        fun2: goto fun1;
        }
      • the following code is valid
        void fun1(){
         printf("fun1");
            {
               
        block1: printf("block1");
            }
            goto
        block1;
        }
  • Type Qualifiers:
    • const
      • Saved in ROM
      • The program can not change this variable
      • Other component other than the program can change the variable (ex: hardware device)
    • volatile
      • To highlight that this variable may be changed, without explicit assignment in the program
        ex:
        may be changed by HW device, by operating system, ...etc
      • This prevents compiler optimization like the following
        • y = x*3/(5x+2);    =======>     y = x*3/(5x+2);
          z = x*3/(5x+2);                 z = y;
  • Storage Class Specifiers:
    • extern  ==> the variabale is defined in other file
      • In some compilers, it is not mandatory to use "extern" key word
    • static
      • in file scope ==> the variable is file global (internal)
      • in block scope ==> the variable shall be initialized only once at the program startup
    • register
      • This variable shall be stored in a register if applicable (faster access)
      • If no registers are available, define them some how to be faster in operations.
      • Allowed for local variables.
      • Theoretically, can be ignored by the compiler if not possible, but this seldom happens.
    • auto
      • The variable is local to the function (no need to write this! all function variables are auto by default)
  • Constants
    • The compiler fits numeric constants to data types as follows:
      • Default fit
        • Integer constant: to the smallest data type fits
          • 16 >> short
          • 100000 >> long
        • Floating point constant: to double
          • 16.3 >> double
      • postfix fit
        • 12.9F or 12.9f >> float
        • 12.9L or 12.9l >> long double
        • 12U or 12u >> unsiged short
        • 12L or 12l >> long int
    • Hexadecimal and Octal
      • 0x10 ==> Hexadecimal
      • 010 ==> Octal
  • Operators:
    • Assignment operator "="
      • Multiple Assignment
        • x = z = 1;
      • Compound assignment
        • x += 1;
    • Arithmatic operators
      • ++ , --
      • - (unary operator)
      • + , / , %
      • + , - 
    • Relational and logical operators
      • !
      • > , >= , < , <=
      • == , !=
      • &&
      • ||
    • Bitwise Operators
      • & , | , ^ , ~
    • Other Operators
      • ? (ternary operator)
      • pointers: * , &
        • pointer operators and unary "-" operator have the highest precedence
    • sizeof()
      • unary operator
      • run time operator
      • returns the size of the operand (in bytes)
      • the return value is of type size_t, where:
        "size_t" is defined to be "unsigned int", using typedef
    • Comma operator
      • separates expressions
      • the result is the last expression result
      • x = (y = 5, y + 1);
        this means:
        • put y = 5
        • then put x = y + 1
    • dot (.) and  arrow (->)
      • dot (.)
        • for struct/union member reference using the struct
      • arrow (->)
        • for struct/union member reference using the struct pointer
    • () and []
      • ()
        • for precedence
      • []
        • for array indexing
    • Precedence
      • Unary operators and ?
        • associate from right to left
      • Other operators
        • associate from left to right
      • Precedence:
        • ()    []    ->    . 
        • !    ~    ++    --    -    (type)    *:at address    &:address of    sizeof
        • *    /    %
        • +    -    
        • <<    >>
        • <    <=    >    >=
        • ==    !=
        • &
        • ^
        • |
        • &&
        • ||
        • ?    :
        • =    +=    -=    *=    /=    etc
        • ,
    • Type promotion in expressions:
      • char,  short ==> int
      • if one operand is long double ==> the other is promoted to long double
      • else if one operand is double ==> the other is promoted to double
      • else if one operand is float ==> the other is promoted to float
      • else if one operand is unsigned long ==> the other is promoted to unsigned long
      • else if one operand is long ==> the other is promoted to long
      • else if one operand is unsigned int ==> the other is promoted to unsigned int
    • Example: 
      • unsigned char x = 0xFF
      • if (~x == 0x00) // evaluates to false
        • because x will be promoted to unsigned int -> 0x000000FF
        • ~x = 0xFFFFFF00

Saturday, June 27, 2015

C Overview


  • History
    • Dennis Richie, invented it, to write the Unix with it -> 1970
    • Previously Unix was written by assembly -> Bad portability :(
      • Rewrite Unix again for each new processor
    • ANSI (American National Standardization Institute), released the first C standard in 1989 ( C89 )
    • Amendment 1 was added to C89 in 1995
    • C89 with Amendment 1 is the base of C++
    • C89 with Amendment 1 is called the C Subset of C++
    • C99 was released by ANSI in 1999
      • Nearly the same as C89  + some added features (Such as: Variable Length Arrays and strict pointer qualifier)

  • Middle Level Language
    • High level features:
      • C is like the High Level Language in the following features:
        • Portable (easy to adapt the program written for a platform to another platform)
        • Supports DataTypes
          • A datatype defines
            • A set of values that the variable can store
            • A set of operations that can be performed on that variable
      • C is unlike the High Level Languages in the following features:
        • C does not support Run-Time Error Checking, like "array index out of bound"
        • C is a Weakly typed language
          • Implicit casting is allowed
          • Implicit casting happens for arguments that does not match the parameter type.
        • C has few keywords:
          • 32 Keyword in C89
          • 5 more Keywords in C99
          • BASIC (a high level language) defined 100 keywords
    • Low Level Features:
      • Manipulation of Bits, Bytes and Addresses
C key words,  from "The Complete C Reference - 4th Edition"
  • C is a Structured Language
    • The code consists of component blocks (functions - while - if - ...etc )
    • goto usage is either forbidden or discouraged
    • Assembly is not a structured language, cause the code contains jumps and branches -> Spaghetti code!

  • C is a programmer language
    • Unlike BASIC language, which is developed for non-programmers to solve simple problems.

  • Compiler Vs Interpreter
    • Interpreter parses one line of code at a time, execute it.
    • Compiler parses the whole program, generates machine code, that is executed.
    • Interpreter parses the code line each time it is being executed
    • Compiler parses the code lines only once.
    • Java is designed for interpretation.
    • C is designed for compilation (However we can make C interpreters, however will not best utilize C)

Friday, June 26, 2015

ET-STM32F103 ARM Cortex board get started

  • Board ET-STM32F103
  • Based on ARM CORTEX-M3
  • Keil uVision
    • can be used to build the project
    • can be used for debugging, using HW "ULINK".
  • Code Worior
    • I was able to build the project using code worrior
    • I opened the debugger, and tried to debug offline (need more investigation)
  • STMicroelectronics Flash loader: used to flash the board with the hex file
    • Connect the usb-to-serial to UART1
    • Switch To Bootloader (from the boot push button on the board)
    • Press reset (from the reset push button on the board)
    • Open the "STMicroelectronics Flash loader"
      • COM3 (check the port from device manager)
      • Baud 115200
      • 8 Bits
      • Parity: even
      • Echo: disabled
      • Timeout: 5

Friday, June 5, 2015

Compiler

Compilation Steps
Very good tutorial
Very good Video tutorial

  • Pre-processing
    • Process the # Directives
  • Lexical Analysis
    • Strips out white spaces and comments
    • Divide the source code into lexemes, Outputs stream of tokens
    • Generates error on illegal lexemes: example:
      • 1_x = 1 + 2;    --> error: identifier the start with number
  • Syntax Analysis
    • Check the code against grammar, generate errors for wrong grammar.
    • Outputs a parse tree
    • Example of errors:
      • x = 1 + ;       --> can not generate parse tree
      • struct mystruct g,x;
        i = g * x;       --> i is not defined, g and x can not be multiplied, however no error is generated from syntax analyzer.
  • Semantic Analysis
    • Program symbol table is created, debug info is inserted
    • Checks the code for logical 
    • Error Examples:
      • struct mystruct g,x;
        i = g * x;    --> the multiplication operation is illegal for structs, i is not defined
      • warning: variable used before initialization
      • int i = "hi";  --> warning: implicit conversion from pointer to integer
  • Intermediate Code Generation
    • IR, Intermediate code Representation, is a machine code independent representation.
    • This helps to keep the parsing part of the compiler unchanged for different targets, while only the synthesis part is changed from target to target.
    • Output: AST (Abstract Syntax Tree) or Pseudo Code.
  • Machine Independent Code Optimization
    • Loop Unrolling
    • Expanding inline functions
    • Dead code removal
  • Code Generation
    • Conver IR code to machine opcodes
  • Machine Dependent Code Optimization
    • Register Allocation

More Details

  • Lexical Analysis (Tokenizing)
    • Input:
      • Is the c code
      • It consists of lexemes
    • Output
      • Tokens
        • a token is a <Token Class, "lexeme"> pair
    • Ex:
      • if (i == j)
            z = 0;
      • This is read by the parser as follows:
        • if (i == j)\n\tz = 0;
      • Step 1: Devide into lexemes:
        • |if| |(|i| |==| |j|)|\n\t|z| |=| |0|;|
      • Step 2: Identify the "Token Class" of each "lexeme"
        Hence, generate the tokens: <class,"lexeme"> pairs
        • <keyword,"if">
        • <whitespace," ">
        • <PAREN_OPEN,"(">
        • <identifier,"i">
        • <whitespace," ">
        • <operator,"==">
        • <whitespace," ">
        • <identifier,"j">
        • <PAREN_CLOSE,")">
        • <whitespace,"\n\t">
        • <identifier,"z">
        • <whitespace," ">
        • <EQ,"=">
        • <whitespace," ">
        • <integer,"0">
        • <SEMI_COLON,";">
      • Token Classes:
        • Whitespace
          • nonempty sequency of blanks, new lines or tabs
        • Integers
        • Keywords
        • Identifiers
        • Operators
        • Normally each "punctuation" lexemes, has its own class:
          • PAREN_O:           (
          • PAREN_C:           )
          • SEMI_COLON:    ;
          • EQ:                       =
  • Parsing (Syntax Analysis)
    • Input:
      • Sequence of tokens from the lexer
    • Output:
      • Parse Tree
    • Parser does the following:
      • Ensure that the the tokens follow C rules, to avoid syntax errors
      • Generates Parse tree:
      • Intermediate representation:
        • AST: Abstract Syntax Tree 
          • Also a pseudo code can replace AST
          • If the compiler supports different languages on different targets, then this AST or Pseudo code is machine independent
          • AST is like the Parse tree, but removing some unneeded info
    • Example:
      Parse Tree:

      The pic is from Online Courses Compiler Course

      Parse Tree Has some unneeded info:

      The pic is from Online Courses Compiler Course
  • AST (Abstract Syntax Tree):
    Generated as a sort of Intermediate Representation

    The pic is from Online Courses Compiler Course

  • Debug info: (mapping source code to machine code) maps functions, instructions in the mapped binary program, to the source code

        binary instruction => Item name, Item type, file name, line number, ...etc)
  • Symbol table: All identifiers in the source code is related to their memory segments and addresses

Compare signed to unsigned

If you have this code:

main(){
    unsigned int x = 5;
    int y = -3;
    if (y>x)
        printf("y is bigger\n\r");
}

What is the output of this?


  • int = signed int
  • when comparing unsigned to signed, the signed is casted into unsigned
  • in our case
    • x = 00000005
    • y = FFFFFFFD   (MSB = sign bit = 1, the other bits shall be the 2's complement of 3)
    • casting u into unsigned, then comparing, y > x --> true
    • the output: "y is bigger"

What about normal operation?
main(){
int x;
int y = -10;
unsigned int z = 4;
x = y + z;

printf("%d\n\r",x);
}

// -6?
// Also y will be casted to unsigned, then added to z,  the result will be correct, thanks to the 2's complement representation
// y + z = FFFFFFF6 + 00000004 = FFFFFFFA = - 6


Ex:

main(){
short x;
 long x2;
short y = -10;
unsigned short z = 4;
x = y + z;
 x2 = y + z;
 x3 = y + (short)z;

printf("%d, %d, %d\n\r",x, x2, x3);
}

in 16 bit machine:

  • y + z = 0xFFF6 + 0x0004 = 0xFFFA
    • x = 0xFFFA
      • Since x is signed, then x = - 6
    • x2 = 0x0000FFFA
      • Since x2 is signed, then x = + 65530
      • No sign extension happened. because (y + z) is unsigned
    • x3 = 0xFFFFFFFA
      • Since x3 is signed, then x = - 6
      • sign extension happened because (y + z) is signed
in 32 bit machine:
  • y + z = 0xFFFFFFF6 + 0x00000004 = 0xFFFFFFFA
    • x = x2 = x3 = - 6

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