Low-level programming language: Difference between revisions

Content deleted Content added
Most of the references for the statement about non-portability are talking about assembly language as the only example of a low-level language; move that to the section about assembly language.
 
(24 intermediate revisions by 11 users not shown)
Line 1:
{{Short description |Programming languageslanguage that provideprovides little or no abstraction from underlying hardware}}
{{multiple issues|
{{original research|date=March 2017}}
{{More citations needed|date=July 2015}}
 
}}
 
A '''low-level programming language''' is a [[programming language]] that provides little or no [[Abstraction (computer science)|abstraction]] from a computer's [[instruction set architecture]], memory or underlying physical hardware; commands or functions in the language are structurally similar to a processor's instructions. These languages provide the programmer with full control over program memory and the underlying machine code instructions. Because of the low level of abstraction (hence the term "low-level") between the language and machine language, low-level languages are sometimes described as being "close to the hardware". Programs written in low-level languages tend to be relatively [[Software portability|non-portable]], due to being optimized for a certain type of system architecture.<ref name=":0">{{Cite web |date=2021-03-05 |title=3.1: Structure of low-level programs |url=https://workforce.libretexts.org/Bookshelves/Information_Technology/Information_Technology_Hardware/Advanced_Computer_Organization_Architecture_(Njoroge)/03%3A_Computer_Organization_and_low-level_Programming/3.01%3A_Structure_of_low-level_programs |access-date=2023-04-03 |website=Workforce LibreTexts |language=en}}</ref><ref>{{Cite web |date=2023-11-19 |title=What is a Low Level Language? |url=https://www.geeksforgeeks.org/what-is-a-low-level-language/ |access-date=2024-04-27 |website=GeeksforGeeks |language=en-US}}</ref><ref>{{Cite web |title=Low Level Language? What You Need to Know {{!}} Lenovo US |url=https://www.lenovo.com/us/en/glossary/low-level-language/ |access-date=2024-04-27 |website=www.lenovo.com |language=en}}</ref><ref>{{Cite web |title=Low-level languages - Classifying programming languages and translators - AQA - GCSE Computer Science Revision - AQA |url=https://www.bbc.co.uk/bitesize/guides/z4cck2p/revision/2 |access-date=2024-04-27 |website=BBC Bitesize |language=en-GB}}</ref>
 
Low-level languages are directly converted to machine code with or without a [[compiler]] or [[Interpreter (computing)|interpreter]]—[[second-generation programming language]]s<ref name=":3">{{Cite web |date=2017-10-22 |title=Generation of Programming Languages |url=https://www.geeksforgeeks.org/generation-programming-languages/ |access-date=2024-04-27 |website=GeeksforGeeks |language=en-US}}</ref><ref name=":4">{{Cite web |title=What is a Generation Languages? |url=https://www.computerhope.com/jargon/num/1gl.htm |access-date=2024-04-27 |website=www.computerhope.com |language=en}}</ref> depending on programming language. A program written in a low-level language can be made to run very quickly, with a small [[memory footprint]]. A program that written with those programming languages often end up becoming architecture dependent or operating system dependent, due to using low level [[API]]s.<ref name=":0" />
 
== Machine code ==
[[File:Digital pdp8-e2.jpg|thumb|Front panel of a [[PDP-8/Ee]] minicomputer. The row of switches at the bottom can be used to toggle in a machine language programcode.]]
{{Main|Machine code}}
''Machine code'' is the form in which code that can be directly executed is stored on a computer. It consists of machine language [[instruction set architecture|instructions]], stored in memory, that perform operations such as moving values in and out of memory locations, arithmetic and Boolean logic, and testing values and, based on the test, either executing the next instruction in memory or executing an instruction at another ___location.
 
Low-level languages are directly converted to machine[[Machine code]], withclassified or withoutas a [[compiler]] or [[Interpreter (computing)|interpreter]]—[[secondfirst-generation programming language]]s,<ref name=":3">{{Cite web |date=2017-10-22 |title=Generation of Programming Languages |url=https://www.geeksforgeeks.org/generation-programming-languages/ |access-date=2024-04-27 |website=GeeksforGeeks |language=en-US}}</ref><ref name=":4">{{Cite web |title=What is a Generation Languages? |url=https://www.computerhope.com/jargon/num/1gl.htm |access-date=2024-04-27 |website=www.computerhope.com |language=en}}</ref> dependingis on[[data]] programming[[encoded]] language.and Astructured programper writtenthe in[[instruction aset low-levelarchitecture]] language can be made to run very quickly, withof a small [[memory footprintCPU]]. AThe programinstructions thatimply writtenoperations withsuch thoseas programmingmoving languagesvalues oftenin endand upout becomingof architecturememory dependentlocations, orBoolean operatinglogic, systemarithmetic, comparing dependentvalues, dueand toflow usingcontrol low(branching leveland [[API]]sjumping).<ref name=":0" />
Machine code is usually stored in memory as [[Binary code|binary]] data. Programmers almost never write programs directly in machine code; instead, they write code in [[assembly language]] or higher-level programming languages.<ref name=":0" />
 
Programmers almost never program directly in machine code; instead, they use an [[assembly language]] or a higher-level programming language.<ref name=":0" /> Although few programs are written in machine languages, some programmers oftenlearn becometo adept at readingread it through workingexperience with [[core dump]]s orand debugging from the front panel.
 
Example of a function in hexadecimal representation of [[x86-64]] machine code to calculate the ''n''th [[Fibonacci number]], with each line corresponding to one instruction:
89 f8
85 ff
74 26
83 ff 02
76 1c
89 f9
ba 01 00 00 00
be 01 00 00 00
8d 04 16
83 f9 02
74 0d
89 d6
ff c9
89 c2
eb f0
b8 01 00 00
c3
 
== Assembly language ==
An [[assembly language]], classified as a [[second-generation programming language]],<ref name=":3"/><ref name=":4"/> provides a level of abstraction on top of machine code. A program written in assembly language is [[Software portability |non-portable]], due to being written and optimized for a particular architecture.<ref name=":0">{{Cite web |date=2021-03-05 |title=3.1: Structure of low-level programs |url=https://workforce.libretexts.org/Bookshelves/Information_Technology/Information_Technology_Hardware/Advanced_Computer_Organization_Architecture_(Njoroge)/03%3A_Computer_Organization_and_low-level_Programming/3.01%3A_Structure_of_low-level_programs |access-date=2023-04-03 |website=Workforce LibreTexts |language=en}}</ref><ref>{{Cite web |date=2023-11-19 |title=What is a Low Level Language? |url=https://www.geeksforgeeks.org/what-is-a-low-level-language/ |access-date=2024-04-27 |website=GeeksforGeeks |language=en-US}}</ref><ref>{{Cite web |title=Low Level Language? What You Need to Know {{!}} Lenovo US |url=https://www.lenovo.com/us/en/glossary/low-level-language/ |access-date=2024-04-27 |website=www.lenovo.com |language=en |url-status=dead |archive-url=https://web.archive.org/web/20240724093734/https://www.lenovo.com/us/en/glossary/low-level-language/ |archive-date=2024-07-24}}</ref><ref>{{Cite web |title=Low-level languages - Classifying programming languages and translators - AQA - GCSE Computer Science Revision - AQA |url=https://www.bbc.co.uk/bitesize/guides/z4cck2p/revision/2 |access-date=2024-04-27 |website=BBC Bitesize |language=en-GB}}</ref>
{{Main|Assembly language}}
 
Second-generation languages provide one abstraction level on top of the machine code. In the early days of coding on computers like [[TX-0]] and [[PDP-1]], the first thing [[MIT]] [[Hacker culture|hackers]] did was to write assemblers.<ref name=":1">{{cite book|last=Levy|first=Stephen|year=1994|title=Hackers: Heroes of the Computer Revolution|title-link=Hackers: Heroes of the Computer Revolution|publisher=Penguin Books|page=32|isbn=0-14-100051-1}}</ref>
Assembly language has little [[Semantics (computer science)|semantics]] or formal specification, being only a mapping of human-readable symbols, including symbolic addresses, to [[opcode]]s, [[memory address|addresses]], numeric constants, [[string (computer science)|strings]] and so on. Typically, one [[machine instruction (computing)|machine instruction]] is represented as one line of assembly code, commonly called a ''mnemonic''.<ref>{{Cite web |title=Machine Language/Assembly Language/High Level Language |url=https://www.cs.mtsu.edu/~xyang/2170/computerLanguages.html |access-date=2024-04-27 |website=www.cs.mtsu.edu |archive-url=https://web.archive.org/web/20241214053921/https://www.cs.mtsu.edu/~xyang/2170/computerLanguages.html |archive-date=2024-12-14 |url-status=dead}}</ref> Assemblers produce [[object file]]s that can [[linker (computing)|link]] with other object files or be [[loader (computing)|loaded]] on their own. Most assemblers provide [[macro (computer science)|macros]] to generate common sequences of instructions.
 
Second-generation languages provide one abstraction level on top of the machine code. In the early days of coding on computers like [[TX-0]] and [[PDP-1]], the first thing [[MIT]] [[Hacker culture|hackers]] did was to write assemblers.<ref name=":1">{{cite book|last=Levy|first=Stephen|year=1994|title=Hackers: Heroes of the Computer Revolution|title-link=Hackers: Heroes of the Computer Revolution|publisher=Penguin Books|page=32|isbn=0-14-100051-1}}</ref>
 
== C programming language ==
The [[C (programming language)|C programming language]], a [[third-generation programming language]],<ref name=":3"/><ref name=":4"/> is sometimes classified as high or low depending on what one means by high vs. low level.<ref>{{cite journal |last1=Jindal |first1=G. |first2=P. |last2=Khurana |first3=T. |last3=Goel |date=January 2013 |title=Comparative study of C, Objective C, C++ programming language |journal=International Journal of Advanced Trends in Computer Science and Engineering |volume=2 |issue=1 |page=203}}</ref> The syntax of C is inherently higher level than that of an assembly language since an assembly language is syntactically platform dependent whereas the C syntax is platform independent. C does support low-level programming {{endash}} directly accessing computer hardware {{endash}} but other languages, sometimes considered higher level than C, also can access hardware directly. With C, developers might need to handle relatively low-level aspects that other languages abstract (provide higher level support for) such as memory management and pointer arithmetic. But, C can encode abstractions that hide details such as hardware access, memory management and pointer arithmetic such that at least part of a C [[codebase]] might be as conceptually high-level as if constructed in any other language. Whether C is classified as high or low level language is contended, but it is higher level than assembly languages (especially syntactically) and is lower level than many other languages in some aspects.
 
Although C is not architecture independent, it can be used to write code that is [[cross-platform]] even though doing so can be technically challenging. An aspect of C that facilitates cross-platform development is the [[C standard library]] that provides “an [[interface (computing)|interface]] to system-dependent objects that is itself relatively system independent”.<ref>{{cite book |last=Kernighan |first=B. |author-link1=Brian Kernighan |last2=Ritchie |first2=D. |author-link2=Dennis Ritchie |date=1988 |title=The C Programming Language, 2nd Edition |page=163}}</ref>
Most assemblers provide [[macro (computer science)|macros]] to generate common sequences of instructions.
 
==Comparison==
ExampleThe offollowing a function in hexadecimal representation ofis [[x86-64]] machine code for an algorithm to calculate the ''n''th [[Fibonacci number]],; with values in [[hexadecimal]] representation and each line corresponding to one instruction:
 
<pre>
89 f8
85 ff
74 26
83 ff 02
76 1c
89 f9
ba 01 00 00 00
be 01 00 00 00
8d 04 16
83 f9 02
74 0d
89 d6
ff c9
89 c2
eb f0
b8 01 00 00
c3
</pre>
 
InThe thisfollowing code example,is the same algorithm written in [[x86 assembly language|x86-64 assembly language]] using [[Intel syntax]]. The [[Processor register |registers]] of the x86-64 processor are named and manipulated directly. The function loads its 64-bit argument from {{code|rdi}} in accordance to the [[x86 calling conventions#System V AMD64 ABI|System V application binary interface for x86-64]] and performs its calculation by manipulating values in the {{code|rax}}, {{code|rcx}}, {{code|rsi}}, and {{code|rdi}} registers until it has finished and returns. Note that in this assembly language, there is no concept of returning a value. The result having been stored in the {{code |rax}} register, again in accordance with System V application binary interface, the {{code |ret}} instruction simply removes the top 64-bit element on the [[Stack-based memory allocation |stack]] and causes the next instruction to be fetched from that ___location (that instruction is usually the instruction immediately after the one that called this function), with the result of the function being stored in {{code |rax}}. x86-64 assembly language imposes no standard for passing values to a function or returning values from a function (and in fact, has no concept of a function); those are defined by an [[application binary interface]] (ABI), such as the System V ABI for a particular instruction set.
 
Example: The same [[Fibonacci number]] calculator as above, but in [[x86 assembly language|x86-64 assembly language]] using [[Intel syntax]]:
<syntaxhighlight lang="asm">
fib:
mov rax, rdi ; put theThe argument is stored in rdi, put it into rax
test rdi, rdi ; isIs itthe argument zero?
je .return_from_fib ; yesYes - return 0, which is already in rax
cmp rdi, 2 ; isNo 2- greatercompare thanthe or equalargument to it?2
jbe .return_1_from_fib ; yes (i.e.,If it's 1is less than or 2)equal -to 2, return 1
mov rcx, rdi ; no -Otherwise, put it in rcx, for use as a counter
mov rdx, 1 ; theThe first previous number in the sequence, which starts out as 1, put it in rdx
mov rsi, 1 ; theThe numbersecond beforeprevious that, whichnumber also starts out as 1, put it in rsi
.fib_loop:
lea rax, [rsi + rdx] ; putPut the sum of the previous two numbers into rax
cmp rcx, 2 ; isIs the counter 2?
je .return_from_fib ; yesYes - rax contains the result
mov rsi, rdx ; No - make the first previous number the number before thesecond previous onenumber
dec rcx ; decrementDecrement the counter
mov rdx, rax ; makeMake the current number the first previous number
jmp .fib_loop ; keepKeep going
.return_1_from_fib:
mov rax, 1 ; setSet the return value to 1
.return_from_fib:
ret ; returnReturn
</syntaxhighlight>
 
ThisThe codefollowing is the same algorithm again, but in C. This is similar in structure to the assembly language example but there are significant differences in terms of abstraction:
In this code example, the [[Processor register|registers]] of the x86-64 processor are named and manipulated directly. The function loads its 64-bit argument from {{code|rdi}} in accordance to the [[x86 calling conventions#System V AMD64 ABI|System V application binary interface for x86-64]] and performs its calculation by manipulating values in the {{code|rax}}, {{code|rcx}}, {{code|rsi}}, and {{code|rdi}} registers until it has finished and returns. Note that in this assembly language, there is no concept of returning a value. The result having been stored in the {{code|rax}} register, again in accordance with System V application binary interface, the {{code|ret}} instruction simply removes the top 64-bit element on the [[Stack-based memory allocation|stack]] and causes the next instruction to be fetched from that ___location (that instruction is usually the instruction immediately after the one that called this function), with the result of the function being stored in {{code|rax}}. x86-64 assembly language imposes no standard for passing values to a function or returning values from a function (and in fact, has no concept of a function); those are defined by an [[application binary interface]] (ABI), such as the System V ABI for a particular instruction set.
* The input (parameter {{code |n}}) is an abstraction that does not specify any storage ___location on the hardware. In practice, the C compiler follows one of many possible [[calling convention]]s to determine a storage ___location for the input.
* The local variables {{code|f_nminus2}}, {{code|f_nminus1}}, and {{code|f_n}} are abstractions that do not specify any specific storage ___location on the hardware. The C compiler decides how to actually store them for the target architecture.
* The return function specifies the value to return, but does not dictate ''how'' it is returned. The C compiler for any specific architecture implements a '''standard''' mechanism for returning the value. Compilers for the x86-64 architecture typically (but not always) use the {{code |rax}} register to return a value, as in the assembly language example (the author of the assembly language example has ''chosen'' to use the System V application binary interface for x86-64 convention but assembly language does not require this).
 
These abstractions make the C code compilable without modification onfor any architecture forthat whichis supported by a C compiler has been written,; whereas the assembly language code above will only runruns on processors using the x86-64 architecture.
Compare this with the same function in [[C (programming language)|C]]:
 
<syntaxhighlight lang="c">
Line 96 ⟶ 104:
}
f_nminus2 = f_nminus1;
f_nminus1 = f_n;
}
}
Line 101 ⟶ 110:
</syntaxhighlight>
 
== Low-level programming in high-level languages ==
This code is similar in structure to the assembly language example but there are significant differences in terms of abstraction:
During the late 1960s and 1970s,Some [[High-level programming language |high-level languages]] that included some degree of access to low-level programming functions, such as [[IBM PL/S|PL/S]], [[BLISS]], [[BCPL]], extended [[ALGOL]] and [[NEWP]] (for [[Burroughs large systems]]/Unisys Clearpath MCP systems), and [[C, (programmingcan language)|C]],access werelower-level introducedprogramming languages. One method for doing this is [[inline assembly]], in which assembly code is embedded in athe high-level language that supports this featurecode. Some of these languages also allow architecture-dependent [[Optimizing compiler |compiler optimization directives]] to adjust the way a compiler uses the target processor architecture.
 
* The input (parameter {{code|n}}) is an abstraction that does not specify any storage ___location on the hardware. In practice, the C compiler follows one of many possible [[calling convention]]s to determine a storage ___location for the input.
* The local variables {{code|f_nminus2}}, {{code|f_nminus1}}, and {{code|f_n}} are abstractions that do not specify any specific storage ___location on the hardware. The C compiler decides how to actually store them for the target architecture.
* The return function specifies the value to return, but does not dictate ''how'' it is returned. The C compiler for any specific architecture implements a '''standard''' mechanism for returning the value. Compilers for the x86-64 architecture typically (but not always) use the {{code|rax}} register to return a value, as in the assembly language example (the author of the assembly language example has ''chosen'' to use the System V application binary interface for x86-64 convention but assembly language does not require this).
 
These abstractions make the C code compilable without modification on any architecture for which a C compiler has been written, whereas the assembly language code above will only run on processors using the x86-64 architecture.
 
== C programming language ==
{{Main | C programming}}
C programming language is low level architecture independent programming language. In the 1980s, C was considered to be high level, a time that direct assembly was common. However due to introduction of high level languages that get interpreted like [[Python (programming language) | Python]],[[Java (programming language) | Java]] and many others that completely abstract from low level detail, C is considered low level.
 
C lacks high level programming characteristics that high level language provide like [[Object-oriented programming | OOPs]]. A programmer can implement his/her own objects and object management methods using functions and structures, but that doesn't make C an object-oriented language.
 
Since the programmer has full control over program memory (including, but not limited to, allocation and deallocation), mismanagement of those resources may result undefined behaviour including program crashes or leaking resources.
 
== Low-level programming in high-level languages ==
During the late 1960s and 1970s, [[High-level programming language|high-level languages]] that included some degree of access to low-level programming functions, such as [[IBM PL/S|PL/S]], [[BLISS]], [[BCPL]], extended [[ALGOL]] and [[NEWP]] (for [[Burroughs large systems]]/Unisys Clearpath MCP systems), and [[C (programming language)|C]], were introduced. One method for this is [[inline assembly]], in which assembly code is embedded in a high-level language that supports this feature. Some of these languages also allow architecture-dependent [[Optimizing compiler|compiler optimization directives]] to adjust the way a compiler uses the target processor architecture.
 
Furthermore, as referenced above, theThe following block of C iscode from the [[GNU Compiler and shows the inline assembly ability of C. Per theCompiler]] (GCC) documentation this is a simple copy and addition code. This code displays the interaction between a generally high level language like C anddemonstrates its middle/lowinline level counter part Assembly. Although this may not make C a natively low level language these facilities express the interactions in a more directassembly wayfeature.<ref>{{Cite web |title=Extended Asm (Using the GNU Compiler Collection (GCC)) |url=https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html |access-date=2024-04-27 |website=gcc.gnu.org}}</ref> <syntaxhighlight lang="c">
int src = 1;
int dst;
Line 135 ⟶ 128:
{{Reflist}}
 
== Bibliography ==
* {{cite book |last1=Zhirkov |first1=Igor |title=Low-level programming: C, assembly, and program execution on Intel 64 architecture |date=2017 |publisher=Apress |___location=California |isbn=978-1-4842-2402-1}}
 
{{Types of programming languages}}