The First Program: Unterschied zwischen den Versionen
Die Seite wurde neu angelegt: „Our first program will initially do nothing; it will simply run an infinite loop. We use it as a foundational building block to create all further experiments. I will first describe how such a program is created, what peculiarities there are, how it is compiled, and then how it is executed. == Creating the Source Code == First, we open our text editor to write our first assembly program. <syntaxhighlight lang="asm"> /* The first program 13.10.2020 www.s…“ |
|||
| Zeile 52: | Zeile 52: | ||
!DESCRIPTION | !DESCRIPTION | ||
|- | |- | ||
|.text |Executable program code | |.text | ||
|Executable program code | |||
This section contains read-only data and cannot be written to | |||
|- | |- | ||
|.data |Data | |.data | ||
|Data | |||
Within this section, data can be read and written. The data is not executable | |||
|- | |- | ||
|.rdata |Similar to .data, but the data cannot be written. This is used, for example, for constants. | |.rdata | ||
|Similar to .data, but the data cannot be written. This is used, for example, for constants. | |||
|- | |- | ||
|.init |Generates code that is only executable at the start of the program. | |.init | ||
|Generates code that is only executable at the start of the program. | |||
|} | |} | ||
== .globl == | == .globl == | ||
In line 6, the label _start is defined as global. This makes the linker aware of this label. In our system, which we must program here, we need to define this label as global so the linker can place our code in memory at address 0x8000. For 32-bit bare-metal applications, the Raspberry Pi expects the program to be exactly there. This is due to the peculiarity of the Raspberry Pi. The Raspberry Pi initially doesn't start with the CPU, but with its graphics chip. A firmware is started there, the Raspberry Pi is initialized, and only then handed over to the CPU. During this time, this memory space is reserved, and the CPU is then assigned to look at memory location 0x8000 and execute the code there. For 64-bit bare-metal applications, the address is 0x80000. | In line 6, the label _start is defined as global. This makes the linker aware of this label. In our system, which we must program here, we need to define this label as global so the linker can place our code in memory at address 0x8000. For 32-bit bare-metal applications, the Raspberry Pi expects the program to be exactly there. This is due to the peculiarity of the Raspberry Pi. The Raspberry Pi initially doesn't start with the CPU, but with its graphics chip. A firmware is started there, the Raspberry Pi is initialized, and only then handed over to the CPU. During this time, this memory space is reserved, and the CPU is then assigned to look at memory location 0x8000 and execute the code there. For 64-bit bare-metal applications, the address is 0x80000. | ||
Version vom 1. April 2025, 12:19 Uhr
Our first program will initially do nothing; it will simply run an infinite loop. We use it as a foundational building block to create all further experiments. I will first describe how such a program is created, what peculiarities there are, how it is compiled, and then how it is executed.
Creating the Source Code
First, we open our text editor to write our first assembly program.
/*
The first program
13.10.2020 www.satyria.de
*/
.section .init @This shows the linker what to consider
.globl _start @Generates a global label
_start: @The label _start (entry address)
b main @Branch to "main"
.section .text @Instruction to the linker that code is coming
main: @Create the label "main"
mov sp,#0x8000 @Create a stack of 32768 bytes
MainLoop: @Infinite loop
b MainLoop
Save this file in the default installation directory on Windows as follows: C:\msys64\home\xxx, where "xxx" usually refers to your name. On Linux, it can be saved in the "Home" directory. Name it erstes.s. The suffix .s designates the file as assembly source code.
First, I will describe the program and the commands used, and in the end, we will compile it.
Comments
In this example, I have highlighted the comments in orange so that they can be better recognized. In the following examples, these will be shown in olive.
There are two types of comments. Comments that span multiple lines start with /* and end with */. This can be seen in lines 1-4 in the example.
In the following lines, @ is used to create a line comment. The comment starts from the @ character and ends at the end of the line.
Sections
Sections in assembly are needed to tell the linker how to handle the following lines.
Our first .section command (line 5) generates an initiation of the program. This code is executed first but should not be called again afterwards. In this section, we jump to our main program.
In line 11, we use the .text section. This information tells the linker that it is executable code. This part is also write-protected.
Here is a selection of possible .section commands:
| SECTION NAME | DESCRIPTION |
|---|---|
| .text | Executable program code
This section contains read-only data and cannot be written to |
| .data | Data
Within this section, data can be read and written. The data is not executable |
| .rdata | Similar to .data, but the data cannot be written. This is used, for example, for constants. |
| .init | Generates code that is only executable at the start of the program. |
.globl
In line 6, the label _start is defined as global. This makes the linker aware of this label. In our system, which we must program here, we need to define this label as global so the linker can place our code in memory at address 0x8000. For 32-bit bare-metal applications, the Raspberry Pi expects the program to be exactly there. This is due to the peculiarity of the Raspberry Pi. The Raspberry Pi initially doesn't start with the CPU, but with its graphics chip. A firmware is started there, the Raspberry Pi is initialized, and only then handed over to the CPU. During this time, this memory space is reserved, and the CPU is then assigned to look at memory location 0x8000 and execute the code there. For 64-bit bare-metal applications, the address is 0x80000.
The First Assembly Commands
In this example, only two assembly instructions have been used so far, b and mov, highlighted in blue.
b (Branch)
b stands for Branch and means that the program should branch.
b main @Branch to "main"
The first Branch command (line 9) means it should jump to the label main, thereby starting our program.
MainLoop: @Infinite loop
b MainLoop
The second Branch command used here means it should jump to the label MainLoop. If you look at the code closely, you will see that a constant jump to the same code section occurs. This creates an infinite loop. We must do this here because otherwise, the program would do something undefined, possibly things we do not want.
A Note on Labels
All labels that are jumped to must be concluded with : in the code. All alphanumeric characters plus a few special characters are allowed. Ideally, one should use meaningful labels so that the code remains readable later on.
mov (Move)
mov sp,#0x8000 @Create a stack of 32768 bytes
The command mov means that information should be moved. In our case, we write the address 0x8000 into the stack pointer (sp) register. We need the stack later in our programs to store temporary data.
A stack operates in a way that the last number placed on it is the first one taken off (LIFO). The stack pointer (sp) negates its position, meaning the first number is stored at memory location 0x8000, and the next at 0x7FFF.
In our case, we reserve memory from 0 to 0x8000 for the stack.
I will describe the mov command in more detail later on; for now, let's just see it in action.
Number Formats
In the example mov, I used the "number" 0x8000. In the comment, the number 32768 is shown. These two numbers are identical. The prefix 0x is used to indicate a hexadecimal number. Without specifying a format, the compiler interprets the number as a decimal. Besides these two formats, there are a few others. Here’s a list:
NUMBER TYPE BASE PREFIX ALLOWED CHARACTERS Decimal 10 - 0-9 Hexadecimal 16 0x or 0X 0-9, A-F Octal 8 O 0-7 Binary 2 0b or 0B 0-1 Floating Point 10 0f or 0F 0-9
The translation has been completed and the content appears accurate. No changes have been noted that would necessitate a summary of modifications.