Part 1 arm assembly syntax in Linux
Although it is convenient to use C or C ++ to write programs in Linux, the assembler source program is used for the most basic initialization of the system, such as initializing the stack pointer, setting the page table, and operating the arm coprocessor. After initialization, you can jump to C code execution. Note that the GNU assembler follows at&t's Assembly syntax and can download the relevant specifications from the GNU website (www.gnu.org.
I. Linux Assembly Line Structure
Any assembly line is structured as follows:
[:] [} @ Comment
[:] [} @ Annotation
In Linux arm assembly, any identifier ending with a colon is considered as a label, not necessarily at the beginning of a line.
[Example 1] define a "add" function and return the sum of the two parameters.
. Section. Text, "X"
. Global add @ give the symbol add external Linkage
Add:
Add r0, R0, R1 @ add input arguments
MoV PC, LR @ return from subroutine
@ End of Program
--------------------------------------------------------------------------------
Ii. labels in Linux Assembler
The label can only be ~ Z, ~ Z, 0 ~ 9, ".", _, and other characters. When the label is 0 ~ When the number is 9, the local label can be repeated as follows:
? Label F: Forward label in the referenced position
? Label B: backward label at the place of reference
[Example 2] example of using a local symbol, a loop Program
1:
Subs r0, R0, #1 @ each loop to make R0 = r0-1
BNE 1f @ jump to 1 to execute
The local label represents the address of the local label. Therefore, it can be used as a variable or function.
Iii. Segmentation in Linux Assembler
(1) Section pseudo operation
You can use the. Section pseudo operation to customize a segment. The format is as follows:
. Section section_name [, "Flags" [, % Type [, flag_specific_arguments]
Each segment starts with its name and ends with the name of the next segment or the end of the file. These segments all have default flags that can be recognized by the connector. (Same as the area in armasm ).
The following section lists the allowed segments in the ELF format.
Description
A allowed segment
W writable segments
X execution segment
[Example 3] definition section
. Section. mysection @ custom data segment named ". mysection"
. Align 2
Strtemp:
. ASCII "Temp string \ n \ 0"
(2) pre-defined segment name of the Assembly System
. Text @ code snippet
. Data @ initialize Data Segment
. BSS @ uninitialized data segment
. Sdata @
. Sbss @
Note that the. BSS segment in the source program should be before. Text.
--------------------------------------------------------------------------------
Iv. Define entry points
The default entry of the assembler is the start mark. You can use the entry mark in the connection script file to specify other entry points.
[Example 4] define the entry point
. Section. Data
. Section. BSS
. Section. Text
. Globl _ start
_ Start:
--------------------------------------------------------------------------------
V. macro definition in Linux Assembler
The format is as follows:
. Macro macro name parameter name list @ pseudodirective. Macro defines a macro
Macro
. Endm @. endm indicates that the macro ends.
If a macro uses a parameter, add the prefix "\" when using this parameter in the macro. Default values can also be used for macro-defined parameters.
You can use the. exitm pseudo command to exit the macro.
[Example 5] macro definition
. Macro shiftleft a, B
. If \ B "indicates not equal, other symbols such as +,-, *,/, %, >>, |, &, ^ ,! , ==, >= ,{,}
Allocate the data space of number_of_bytes bytes and fill in the value of fill_byte. If this value is not specified, it is filled with 0 by default. (Same as the space function in armasm)
--------------------------------------------------------------------------------
6. Word {,}...
Insert a 32-bit data queue. (Same as DCD in armasm)
You can use. Word to use the identifier as a constant.
For example:
Start:
Valueofstart:
. Word start
In this way, the start of the program is saved into the memory variable valueofstart.
--------------------------------------------------------------------------------
VII. hword {,}...
Insert a 16-bit data queue. (Same as dcw in armasm)
8. special characters and syntax of GNU Arm Assembly
Comment symbol in the code line :'@'
Comment on the entire line :'#'
Statement separator :';'
Prefix of the direct operand: '#' or '$'
Part 2 GNU Compiler and debugging tools
I. Compilation tools
1. Introduction to editing tools
The compilation tools provided by GNU include assembler as, C compiler GCC, C ++ compiler g ++, connector lD, and Binary Conversion Tool objcopy. The tools based on the ARM platform are arm-Linux-as, arm-Linux-GCC, arm-Linux-G ++, arm-Linux-LD, and arm-Linux-objcopy. The GNU Compiler is very powerful and has hundreds of operation options, which is also the cause of this headache for beginners. However, in actual development, you only need to use a few limited items, most of which can adopt the default option. The development process of the GNU tool is as follows: Compile the C and C ++ languages or compile the source program, use GCC or G ++ to generate the target file, and write the connection script file, use a connector to generate the final target file (ELF format), and use a binary conversion tool to generate downloadable binary code.
(1) compile C and C ++ languages or assembler source programs
The Assembly source program is usually used for the most basic initialization of the system, such as initializing the stack pointer, setting the page table, and operating the arm coprocessor. After initialization, you can jump to C code execution. Note that the GNU assembler follows at&t's Assembly syntax. You can download the relevant specifications from the GNU website (www.gnu.org. The default entry of the assembler is the start mark. You can also use the entry mark in the connection script file to specify other entry points (see the description of the connection script below ).
(2) Use GCC or G ++ to generate the target file
If the application contains multiple files, you need to compile them separately and connect them with connectors. For example, the author's boot program contains three files: init. S (assembly code, initialization hardware) xmrecever. C (communication module, xmode Protocol) and flash. C (flash erase module ). Use the following command to generate the target file: The arm-linux-gcc-c-O2-oinit.oinit.s arm-linux-gcc-c-O2-oxmrecever.oxmrecever.c arm-linux-gcc-c-O2-oflash.oflash.c where the-C command indicates that only the target code is generated, not connected; The-O command specifies the name of the target file; -O2 indicates second-level optimization. After optimization, the generated code is shorter and the running speed is faster. If the project contains many files, you need to compile the MAKEFILE file. For more information about makefile, see references.
(3) Write a connection script file
GCC and other compilers have built-in default Connection Scripts. If the default script is used, the generated target code must be loaded and run by the operating system. To be able to run directly on an embedded system, you need to write your own connection script file. To write a connection script, you must first understand the format of the target file. The target file generated by the GNU Compiler is in ELF format by default. The ELF File consists of several sections. Unless otherwise specified, the target code generated by the C source program contains the following sections :. text (body segment) contains the instruction code of the program ;. data (Data Segment) contains fixed data, such as constants and character strings ;. BSS (uninitialized data segment) contains uninitialized variables and arrays. The target code generated by the C ++ source program also includes. Fini (destructor code) and. INIT (constructor code. The task of the connector is to connect the. Text,. Data, And. BSS segments of multiple target files, and the connection script file tells the connector where to place these segments. For example, the connection file link. LDS is:
Entry (BEGIN)
Section
{
. = 0x30000000;
. Text: {* (. Text )}
. Data: {* (. Data )}
. BSS: {* (. BSS )}
}
Entry (BEGIN) indicates that the entry point of the program is the begin label ;. = 0x00300000 indicates that the starting address of the target code is 0x30000000, and the block ram address is mx1 ;. text :{*(. text)} indicates the code segment where all target files are placed starting from 0x30000000, followed. data :{*(. data)} indicates that the data segment starts from the end of the code segment, followed. BSS segment.
(4) use a connector to generate the final target file
With the connection script file, the following command can generate the final target file: Arm-Linux-LD-No stadlib-O Bootstrap. elf-tlink. LDS init. O xmrecever. O flash. O
Ostadlib indicates that the database is not connected to the operating system, but directly from the begin entry;-O indicates the name of the target file; -T indicates the connection script file used (you can also use-ttext address to indicate the address of the execution zone), and finally the list of target files to be connected.
(5) generate binary code
The ELF file generated by the connection cannot be downloaded and executed directly. You can use the objcopy tool to generate the final binary file:
Arm-Linux-objcopy-O binary Bootstrap. Elf Bootstrap. Bin
-O binary indicates that a binary file is generated. Objcopy can also generate files in S format. You only need to replace the parameter with-o srec. You can also use the-s option to remove all symbolic information and relocation information. If you want to decompile the generated target code, you can also use the objdump tool:
Arm-Linux-objdump-D Bootstrap. Elf
So far, the generated target file can be directly written to flash for running.
2. makefile instance
Example: head. s main. c
Arm-Linux-gcc-c-o head. O head. s
Arm-Linux-gcc-c-o main. O main. c
Arm-Linux-LD-tlink. LDS head. O ain. O-o example. Elf
Arm-Linux-objcopy-O Binary-s example_tmp.o example
Arm-Linux-objdump-D-B Binary-M arm example> TTT. s
Ii. debugging tools
Linux GNU debugging tools include GDB, gdbserver, and kgdb. GDB and gdbserver can remotely debug applications in Linux on the target board. Gdbserver is a small application running on the target board. It monitors the running of the debugged process and communicates with GDB on the host computer through a serial port. Developers can control the running of processes on the target board and view the content of memory and registers by running gdb commands on the host computer. In Versions later than gdb5.1.1, support for ARM processors is added, and the-target = arm parameter is added during initialization to directly generate a gdbserver Based on the ARM platform. The GDB Tool can be downloaded from ftp: // ftp.gnu.org/pub/gnu/gdb.
For Linux kernel debugging, you can use the kgdb tool. You also need to use the serial port to communicate with GDB on the host computer to debug the Linux Kernel on the target board. You can go to http://oss.sgi.com/projects/kgdb/to learn how to use it.