Source code and object code are essential parts of the process that turns human-written programs into machine-executable software. Understanding their roles is key to mastering software development.
What is source code?
Source code is the collection of human-readable instructions written by a programmer using a high-level programming language or assembly language. It represents the original logic, structure, and operations intended by the developer and must be translated into machine code before it can be executed.
Characteristics of source code
Human-readable: Designed to be read, understood, and modified by programmers.
Written in high-level or assembly languages: High-level languages such as Python, Java, and C++ provide abstraction from the hardware, while assembly language uses symbolic code close to machine instructions.
Text-based: Stored in plain text files with specific file extensions such as .py, .java, .c, .cpp, .asm.
Structured: Organised using syntax rules, keywords, variables, data types, functions, loops, and conditionals depending on the language.
Editable: Programmers can modify, extend, and debug source code as needed.
Not executable by itself: Requires translation by a compiler, assembler, or interpreter into machine code to be run.
Example of source code
python
Practice Questions
FAQ
No, object code is typically specific to the machine architecture and operating system it was compiled for. This is because the binary instructions in object code are tailored to a particular CPU’s instruction set, such as x86, ARM, or MIPS. If you try to execute object code on a machine with a different architecture, the CPU may not recognise the instructions, leading to errors or failure to run. Even differences in operating systems (e.g. Windows vs Linux) can cause incompatibility due to differences in how executables are structured, system calls are handled, and libraries are linked. To run a program across different platforms, you would need to either recompile the source code on each target machine or use an intermediate representation such as bytecode with a virtual machine. In professional software development, cross-compilation tools can be used to generate object code for different systems, but this still requires configuration for each target architecture and OS.
Relocatable object code contains instructions and data with symbolic references that are not yet fixed to specific memory addresses. This type of object code is produced by compilers and assemblers during the initial translation phase and is designed to be flexible so that a linker can adjust the memory addresses during the linking process. In contrast, absolute object code has fixed memory addresses already assigned, making it ready for execution or embedding in a specific memory location. Relocatable code enables modular development where different object files or libraries can be independently compiled and later linked into a complete program. It allows the linker to resolve addresses and resolve symbol references such as function calls or global variables. Absolute object code is more rigid and typically used in embedded systems where code is loaded into specific memory regions. Most high-level programming workflows use relocatable object code to support flexible, maintainable, and scalable program builds.
Editing object code directly is highly impractical and error-prone because it is composed of machine-level binary instructions that are not human-readable and lack the structure and clarity of high-level code. Object code does not include meaningful variable names, comments, or clear logic flow, making it extremely difficult to understand what each part of the program is doing. Even small changes require knowledge of binary encoding, instruction formats, memory addressing, and processor architecture. Any error in editing could corrupt the code and cause the program to crash or behave unpredictably. Furthermore, many development tools are designed to work with source code, not object code, which means debugging, testing, and version control are virtually impossible without the source. Source code is meant to be the editable representation of a program. Any necessary change should be made at that level, after which the program can be recompiled to generate updated object code.
Object code supports modularity by allowing individual source files or program modules to be compiled independently into separate object files. Each object file typically represents one component, class, or functionality within a larger program. This modular approach enables developers to build and test components in isolation, reducing complexity and allowing team members to work in parallel on different parts of the same project. When changes are made to a specific module, only that source file needs to be recompiled, rather than the entire codebase. During linking, the linker combines all the relevant object files into a single executable, resolving references between modules and incorporating any necessary libraries. This approach not only saves time during development but also enhances maintainability and code reuse. Libraries, which are essentially collections of precompiled object files, can be linked into multiple projects without needing access to the original source code, making modularity a key benefit of using object code.
An object file contains more than just machine instructions. It includes metadata and structural information necessary for the linker to correctly combine it with other object files. This typically includes a symbol table, which lists all the functions and variables defined and referenced in the file. The symbol table helps the linker resolve external references, such as a function called in one file but defined in another. There is also a relocation table, which indicates where in the object code memory addresses need to be adjusted during linking. Additionally, section headers define segments of the object code such as the text section (containing instructions), the data section (for initialised variables), and the bss section (for uninitialised variables). Some object files may also include debug information, which maps machine code back to source lines to support debugging tools. Together, these elements make the object file a vital intermediate step in the compilation process.
