0% found this document useful (0 votes)
8 views35 pages

Assembler, Compiler, and Interpreter Guide

Uploaded by

srinivaas
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views35 pages

Assembler, Compiler, and Interpreter Guide

Uploaded by

srinivaas
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Chapter 2

• Embedded C programming: Assembler, Compilers and


interpreter. Data types and its syntax, preprocessors. IDE and
refereeing to its manuals. Startup code. Continuous while loop.
Accessing of internal, external memory of code and data
memory. Look up tables. Debugging techniques. Build system
Assembler, Compilers, and Interpreter:
• Assembler: Translates assembly language code into machine code.
• Compilers: Translate high-level language (like C) into machine code.
• Interpreter: Executes code directly without compiling it into machine
code.
Assembler
• An assembler is a program that translates assembly language code
into machine code, which is the binary representation of instructions
that a computer's CPU can execute.
• Assembly language is a low-level programming language that closely
corresponds to the instructions of a specific CPU architecture.
• Assemblers typically provide mnemonic representations of machine
instructions and symbols for memory addresses, making it easier for
programmers to write code at a more human-readable level than
directly in binary.
Compilers:
• A compiler is a program that translates high-level programming
languages (such as C, C++, Java, etc.) into machine code or
intermediate code.
• The compilation process involves several stages, including lexical
analysis, parsing, semantic analysis, optimization, and code
generation.
• The output of a compiler is typically a binary executable file or an
intermediate representation that can be further processed or
executed.
Interpreter:
• An interpreter is a program that directly executes source code written
in a high-level programming language without prior compilation into
machine code.
• Interpreters typically read the source code line by line, analyze it, and
execute it on the fly.
• Languages like Python, JavaScript, and Ruby often use interpreters,
allowing for dynamic and interactive development environments.
Aspect Assembler Compiler Interpreter
Translates assembly language code to Translates high-level language Executes source code directly without
Purpose
machine code code to machine code or IR prior compilation
High-level programming
Input Language Assembly language High-level programming language
language
Binary executable or intermediate Intermediate representation or directly
Output Machine code
code executed code

Often tightly integrated into IDE with Integrated as part of the build May be integrated or run separately
Integration
syntax highlighting process with error reporting depending on the language

Provides assembly-level debugging Supports source-level debugging Debugging often involves line-by-line
Debugging
features with breakpoints and watchpoints execution and inspection

Typically manual optimization at the Compiler performs optimizations Limited optimization capabilities
Optimization
assembly level based on language constructs compared to compiled languages
Can provide fine-tuned control over Optimizations can lead to efficient Dynamic execution may result in
Performance
hardware resources code execution slower performance
Keil µVision, MPLAB X, Atmel
Studio, GCC, Clang, Visual Python interpreter, [Link], Ruby
Examples Keil µVision, MPLAB X, Atmel Studio
Studio, IAR Embedded interpreter
Workbench
Compilation steps for Keil uVision IDE for the 8051 microcontroller:

1. Source Files:
•Source files typically have extensions like .c for C source code or .asm for assembly source code.
[Link]:
•Preprocessor directives are processed, which may include inclusion of header files (#include),
•macro expansions (#define), conditional compilation (#ifdef, #ifndef), etc.
•Intermediate file after preprocessing: .i or .pre (not usually visible in the IDE).
[Link]:
•Each source file is compiled into assembly language or machine code specific to the target microcontroller architecture.
•Compiled assembly files: .obj or .o.
[Link]:
•Assembly files are translated into machine code specific to the target microcontroller.
•Generated object files: .obj or .o.
[Link]:
•All object files along with library files are combined and resolved into a single executable file.
•The linker resolves symbols, allocates memory locations, and generates the final binary file.
•Generated executable or binary file: .hex, .bin, .out, .a51, etc.
[Link] Files:
•The final output files are typically in a format suitable for flashing onto the microcontroller.
KeilµVision software development cycle
Startup Code
What purpose does the start-up code has in an
MCU?
• Start-Up Code is the soul of an MCU. It is the first-ever code that runs
on an MCU right after the Power On Reset (POR). The Start-Up code
triggers the initializing of crucial parts of the MCU needed for booting
and the subsequent target application launch.
• The start-up code in embedded systems is typically lightweight and is
written in assembly language, or a combination of C and assembly.
When code is written in assembly language, the developer has
greater control and can optimize for speed by carefully selecting
specific instructions or instruction types.
Start-Up Code performs several essential tasks to get the MCU ready to
run the target application.
These Tasks include :
1. Stack Pointer Initialization: Stack Pointer points to the memory
location in RAM which will be used by the program to store the
function call stacks and the local variables for each function call. Start-
Up Code initializes the Stack Pointer with the known Stack location
address (The top address of the stack).
2. Data Section Initialization: Data Section in the memory layout
contains the initialized global and static variables. Start-Up code
initializes the data Section from the FLASH/ROM or any other location
in the memory to the RAM or the memory where code execution will
happen.
3. Block Started by symbol (BSS) Initialization: BSS Section in the
memory layout contains uninitialized global and static variables. The
Start-Up code initializes the BSS Section with zero, to make sure all the
variables get some known value.
4. Vector Table Initialization: The vector table contains the function
pointers of the interrupt callback functions. The Initialization Code for
the Start-Up sets the Vector table location to the value stored in the
vector table section of memory, allowing the designated interrupt
callback to be executed each time an interrupt is triggered.
5. Configuring the Clock and Debug Setting: Depending upon the
application, the clock setting defers so Start-Up can take care of the
default clock settings or even the complete clock settings and ensures
the application code runs at the correct [Link] Start-Up code also
sets the debug settings required for the MCU Platform e.g.
enabling/disabling the JTAG/SWD for debugging, and
enabling/disabling and configuring the UART for debug prints.
6. All the start-up code tasks execution is done by the reset handler
function. After completing all start-up code tasks, the reset handler
exits and transfers control to the main() function, beginning execution
of the target application.
Keil Startup Code
Startup code is executed immediately upon reset of the target system. The
Keil startup code performs (optionally) the following operations in order:
• Clears internal data memory
• Clears external data memory
• Clears paged external data memory
• Initializes the small model reentrant stack and pointer
• Initializes the large model reentrant stack and pointer
• Initializes the compact model reentrant stack and pointer
• Initializes the 8051 hardware stack pointer
• Transfers control to code that initializes global variables or to the main C
function if there are no initialized global variables
Different Startup files
Startup File Description
STARTUP.A51 Startup code for classic 8051 devices.
START_AD.A51 Startup code for Analog Devices MicroConverter devices.
Startup code for Dallas DS80C390/400/41x/5240/5250
START390.A51
contiguous mode devices.
START4XX.A51 Startup code for Dallas DS89C420/430/440/450 devices.

STARTLPC.A51 Startup code for NXP LPC700 devices series.

START900.A51 Startup code for NXP LPC90x - LPC93x devices series.

START950.A51 Startup code for NXP LPC95x - LPC99x devices series.

START_MX.A51 Startup code for NXP 80C51MX devices.


START751.A51 Startup code for NXP 80C75x devices.
START_XC.A51 Startup code for Infineon XC800 devices.
STARTUP32.A51 Startup code for ST uPSD32xx devices.
STARTUP34.A51 Startup code for ST uPSD33xx devices.
STARTUP34.A51 Startup code for ST uPSD34xx devices.
Assembly constants you may change to
control the operations performed at startup.
Name Description

Specifies the number of bytes of idata to clear to 0. The


default is 80h because most 8051 derivatives contain at
IDATALEN least 128 bytes of internal data memory. Use a value of
100h for the 8052 and other derivatives that have 256
bytes of internal data memory.

XDATASTART Specifies the initial xdata address to clear to 0.


Indicates the number of bytes of xdata to clear to 0. The
XDATALEN
default is 0.
PDATASTART Specifies the initial pdata address to clear to 0.
Specifies the number of bytes of pdata to clear to 0. The
PDATALEN
default is 0.
Specifies whether or not the small model reentrant stack
pointer (?C_IBP) should be initialized. A value of 1 causes
IBPSTACK
this pointer to be initialized. A value of 0 prevents
initialization of this pointer. The default is 0.
Specifies whether or not the large model reentrant stack pointer (?C_XBP)
XBPSTACK should be initialized. A value of 1 causes this pointer to be initialized. A value of
0 prevents initialization of this pointer. The default is 0.
Specifies the top of the large model reentrant stack. The default is 0xFFFF in
xdata memory.
XBPSTACKTOP
The Cx51 Compiler does not check to see if the stack area available satisfies the
requirements of the application. It is your responsibility to perform such a test.
Specifies whether the compact model reentrant stack pointer (?C_PBP) should
PBPSTACK be initialized. A value of 1 causes this pointer to be initialized. A value of 0
prevents initialization of this pointer. The default is 0.
Specifies the top of the compact model reentrant stack. The default is 0xFF in
pdata memory.
PBPSTACKTOP
The Cx51 Compiler does not check to see if the stack area available satisfies the
requirements of the application. It is your responsibility to perform such a test.
Enables (a value of 1) or disables (a value of 0) Port 2 initialization for pdata
PPAGEENABLE memory access. The default is 0. pdata addressing uses Port 2 for the upper
address (or page) byte.
Specifies the value to write to Port 2 of the 8051 for pdata memory access. This
value represents the xdata memory page to use for pdata. This is the upper 8 bits
of the absolute address range to use for pdata. For example, if the pdata area
begins at address 1000h (page 10h) in xdata memory, PPAGEENABLE should
be set to 1, and PPAGE should be set to 10h. You must specify the starting pdata
PPAGE
address to use to the BL51 Linker using the PDATA directive. For example:
BL51 input modules PDATA (1050H)
Neither the BL51 Linker nor the Cx51 Compiler checks to see if
the PDATA directive and the PPAGE startup constant are correctly specified.
You must ensure that these parameters contain suitable values.
Steps for Startup Code in 8051 Keil
Continuous while loop
Accessing of internal, external memory of
code and data memory
The 8051 architecture provides various memory spaces, including internal code and data
memory, as well as external data memory (XDATA). Here's how you can access these
memory spaces:
Internal Code Memory (ROM):
• Internal code memory in the 8051 microcontroller holds the program code to be
executed.
• To access internal code memory, you simply specify the memory address where your
code is stored and execute instructions from that address.
• For example:

• org 0x0000 ; Start address of internal code memory


main:
; Your code here
Internal Data Memory (RAM):
• Internal data memory (RAM) is used for storing variables and other
data during program execution.
• To access internal data memory, you use direct addressing with the
appropriate register or memory location.
• For example:
MOV A, 0x30 ; Move the value at address 0x30 into register A
External Data Memory (XDATA):

•The 8051 microcontroller supports external data memory for additional storage beyond the limited internal RAM.
•To access external data memory (XDATA), you need to use special instructions (MOVX, MOVC) that support indirect
addressing.
•You also need to specify the memory address range for XDATA in your program setup.
•For example:

MOVX A, @DPTR ; Move the value from external data memory pointed by DPTR into register A
Data Memory Access Directives:
You may need to define memory segments and their addresses explicitly
using assembly directives to access specific memory spaces.
• For example:
IDATA SEGMENT AT 0x30
variable DB 0xFF
IDATA ENDS
• Remember that accessing external memory may require additional setup,
such as configuring the memory interface and setting up the appropriate
data pointers (DPTR). Additionally, you need to ensure that the memory
addresses you access are valid and do not conflict with other parts of your
program or with hardware registers.
Introduction:
• Lookup tables are data structures commonly used in embedded C
programming for efficient data retrieval and manipulation. They
consist of precomputed values stored in an array or similar data
structure, allowing quick access to data based on specific input values
or indices.
• Key Concepts:
Purpose of Lookup Tables:
• Lookup tables serve various purposes in embedded systems, such as:
• Mapping input values to output values (e.g., sensor readings to physical quantities).
• Storing precomputed results to avoid repetitive calculations.
• Implementing fast data retrieval algorithms.
• Structure of Lookup Tables:
• Lookup tables are typically represented as arrays in C programming.
• Each element in the array corresponds to a specific input value or
index.
• The value stored at each index represents the precomputed or
predefined output value.
• Implementation:
• Define the size of the lookup table based on the application
requirements.
• Initialize the lookup table with precomputed values.
• Retrieve values from the lookup table based on input conditions or
indices.
• Example:

• Consider a scenario where we have an ADC (Analog-to-Digital Converter)


with a resolution of 10 bits.
• We want to create a lookup table for mapping analog voltages to
corresponding digital values.
• Define a lookup table array ‘analogToDigital’ with a size corresponding to
the ADC resolution (e.g., 1024 entries for 10 bits).
• Initialize the lookup table with precomputed digital values corresponding
to analog voltages.
• Retrieve digital values from the lookup table based on input voltages using
appropriate scaling and indexing techniques.
• Benefits of Lookup Tables:
• Efficient data retrieval: Lookup tables provide constant-time access to
precomputed values, resulting in faster execution compared to
calculating values on-the-fly.
• Reduced computational complexity: By precomputing values and
storing them in a lookup table, repetitive calculations can be avoided,
leading to improved performance and efficiency.
• Simplified code: Lookup tables help in organizing and structuring
data, making the code more readable and maintainable.
• #include <stdio.h>

Example •

// Define the size of the lookup table
#define TABLE_SIZE 1024
• // Define the lookup table
• const uint16_t analogToDigital[TABLE_SIZE] = {
• // Table entries go here, representing digital values corresponding to analog voltages
• // For demonstration, we'll fill the table with linearly increasing values
• 0, 1, 2, 3, ..., 1022, 1023
• };

• int main() {
• float inputVoltage = 2.5; // Example input voltage in volts
• uint16_t digitalValue;

• // Convert the input voltage to a digital value using the lookup table
• // For simplicity, we'll assume that the input voltage is directly proportional to the index in the table
• // In practice, you may need to scale or map the input voltage to fit within the range of the table
• int index = (int)(inputVoltage * (TABLE_SIZE - 1) / 5.0); // Scale input voltage to fit table range
• digitalValue = analogToDigital[index];
• // Print the result
• printf("Input Voltage: %.2f V, Digital Value: %u\n", inputVoltage, digitalValue);
• return 0;
• }

You might also like