ARM-GCC编译

本文详细介绍了ARM架构下的编译选项,包括ABI选择、指令集兼容性、浮点运算配置等,帮助开发者针对不同应用场景优化代码。
ARM Options

These `-m' options are defined for Advanced RISC Machines (ARM) architectures:

-mabi=name
Generate code for the specified ABI. Permissible values are: `apcs-gnu', `atpcs', `aapcs', `aapcs-linux' and `iwmmxt'.
-mapcs-frame
Generate a stack frame that is compliant with the ARM Procedure Call Standard for all functions, even if this is not strictly necessary for correct execution of the code. Specifying -fomit-frame-pointer with this option will cause the stack frames not to be generated for leaf functions. The default is -mno-apcs-frame.
-mapcs
This is a synonym for -mapcs-frame.
-mthumb-interwork
Generate code which supports calling between the ARM and Thumb instruction sets. Without this option the two instruction sets cannot be reliably used inside one program. The default is -mno-thumb-interwork, since slightly larger code is generated when -mthumb-interwork is specified.
-mno-sched-prolog
Prevent the reordering of instructions in the function prolog, or the merging of those instruction with the instructions in the function's body. This means that all functions will start with a recognizable set of instructions (or in fact one of a choice from a small set of different function prologues), and this information can be used to locate the start if functions inside an executable piece of code. The default is -msched-prolog.
-mfloat-abi=name
Specifies which floating-point ABI to use. Permissible values are: `soft', `softfp' and `hard'.

Specifying `soft' causes GCC to generate output containing library calls for floating-point operations. `softfp' allows the generation of code using hardware floating-point instructions, but still uses the soft-float calling conventions. `hard' allows generation of floating-point instructions and uses FPU-specific calling conventions.

Using -mfloat-abi=hard with VFP coprocessors is not supported. Use -mfloat-abi=softfp with the appropriate -mfpu option to allow the compiler to generate code that makes use of the hardware floating-point capabilities for these CPUs.

The default depends on the specific target configuration. Note that the hard-float and soft-float ABIs are not link-compatible; you must compile your entire program with the same ABI, and link with a compatible set of libraries.

-mhard-float
Equivalent to -mfloat-abi=hard.
-msoft-float
Equivalent to -mfloat-abi=soft.
-mlittle-endian
Generate code for a processor running in little-endian mode. This is the default for all standard configurations.
-mbig-endian
Generate code for a processor running in big-endian mode; the default is to compile code for a little-endian processor.
-mwords-little-endian
This option only applies when generating code for big-endian processors. Generate code for a little-endian word order but a big-endian byte order. That is, a byte order of the form `32107654'. Note: this option should only be used if you require compatibility with code for big-endian ARM processors generated by versions of the compiler prior to 2.8.
-mcpu=name
This specifies the name of the target ARM processor. GCC uses this name to determine what kind of instructions it can emit when generating assembly code. Permissible names are: `arm2', `arm250', `arm3', `arm6', `arm60', `arm600', `arm610', `arm620', `arm7', `arm7m', `arm7d', `arm7dm', `arm7di', `arm7dmi', `arm70', `arm700', `arm700i', `arm710', `arm710c', `arm7100', `arm720', `arm7500', `arm7500fe', `arm7tdmi', `arm7tdmi-s', `arm710t', `arm720t', `arm740t', `strongarm', `strongarm110', `strongarm1100', `strongarm1110', `arm8', `arm810', `arm9', `arm9e', `arm920', `arm920t', `arm922t', `arm946e-s', `arm966e-s', `arm968e-s', `arm926ej-s', `arm940t', `arm9tdmi', `arm10tdmi', `arm1020t', `arm1026ej-s', `arm10e', `arm1020e', `arm1022e', `arm1136j-s', `arm1136jf-s', `mpcore', `mpcorenovfp', `arm1156t2-s', `arm1176jz-s', `arm1176jzf-s', `cortex-a8', `cortex-a9', `cortex-r4', `cortex-r4f', `cortex-m3', `cortex-m1', `xscale', `iwmmxt', `iwmmxt2', `ep9312'.
-mtune=name
This option is very similar to the -mcpu= option, except that instead of specifying the actual target processor type, and hence restricting which instructions can be used, it specifies that GCC should tune the performance of the code as if the target were of the type specified in this option, but still choosing the instructions that it will generate based on the cpu specified by a -mcpu= option. For some ARM implementations better performance can be obtained by using this option.
-march=name
This specifies the name of the target ARM architecture. GCC uses this name to determine what kind of instructions it can emit when generating assembly code. This option can be used in conjunction with or instead of the -mcpu= option. Permissible names are: `armv2', `armv2a', `armv3', `armv3m', `armv4', `armv4t', `armv5', `armv5t', `armv5e', `armv5te', `armv6', `armv6j', `armv6t2', `armv6z', `armv6zk', `armv6-m', `armv7', `armv7-a', `armv7-r', `armv7-m', `iwmmxt', `iwmmxt2', `ep9312'.
-mfpu=name -mfpe=number -mfp=number
This specifies what floating point hardware (or hardware emulation) is available on the target. Permissible names are: `fpa', `fpe2', `fpe3', `maverick', `vfp', `vfpv3', `vfpv3-d16' and `neon'. -mfp and -mfpe are synonyms for -mfpu=`fpe'number, for compatibility with older versions of GCC.

If -msoft-float is specified this specifies the format of floating point values.

-mstructure-size-boundary=n
The size of all structures and unions will be rounded up to a multiple of the number of bits set by this option. Permissible values are 8, 32 and 64. The default value varies for different toolchains. For the COFF targeted toolchain the default value is 8. A value of 64 is only allowed if the underlying ABI supports it.

Specifying the larger number can produce faster, more efficient code, but can also increase the size of the program. Different values are potentially incompatible. Code compiled with one value cannot necessarily expect to work with code or libraries compiled with another value, if they exchange information using structures or unions.

-mabort-on-noreturn
Generate a call to the function abort at the end of a noreturn function. It will be executed if the function tries to return.
-mlong-calls -mno-long-calls
Tells the compiler to perform function calls by first loading the address of the function into a register and then performing a subroutine call on this register. This switch is needed if the target function will lie outside of the 64 megabyte addressing range of the offset based version of subroutine call instruction.

Even if this switch is enabled, not all function calls will be turned into long calls. The heuristic is that static functions, functions which have the `short-call' attribute, functions that are inside the scope of a `#pragma no_long_calls' directive and functions whose definitions have already been compiled within the current compilation unit, will not be turned into long calls. The exception to this rule is that weak function definitions, functions with the `long-call' attribute or the `section' attribute, and functions that are within the scope of a `#pragma long_calls' directive, will always be turned into long calls.

This feature is not enabled by default. Specifying -mno-long-calls will restore the default behavior, as will placing the function calls within the scope of a `#pragma long_calls_off' directive. Note these switches have no effect on how the compiler generates code to handle function calls via function pointers.

-msingle-pic-base
Treat the register used for PIC addressing as read-only, rather than loading it in the prologue for each function. The run-time system is responsible for initializing this register with an appropriate value before execution begins.
-mpic-register=reg
Specify the register to be used for PIC addressing. The default is R10 unless stack-checking is enabled, when R9 is used.
-mcirrus-fix-invalid-insns
Insert NOPs into the instruction stream to in order to work around problems with invalid Maverick instruction combinations. This option is only valid if the -mcpu=ep9312 option has been used to enable generation of instructions for the Cirrus Maverick floating point co-processor. This option is not enabled by default, since the problem is only present in older Maverick implementations. The default can be re-enabled by use of the -mno-cirrus-fix-invalid-insns switch.
-mpoke-function-name
Write the name of each function into the text section, directly preceding the function prologue. The generated code is similar to this:
               t0
                   .ascii "arm_poke_function_name", 0
                   .align
               t1
                   .word 0xff000000 + (t1 - t0)
               arm_poke_function_name
                   mov     ip, sp
                   stmfd   sp!, {fp, ip, lr, pc}
                   sub     fp, ip, #4
     

When performing a stack backtrace, code can inspect the value of pc stored at fp + 0. If the trace function then looks at location pc - 12 and the top 8 bits are set, then we know that there is a function name embedded immediately preceding this location and has length ((pc[-3]) & 0xff000000).

-mthumb
Generate code for the Thumb instruction set. The default is to use the 32-bit ARM instruction set. This option automatically enables either 16-bit Thumb-1 or mixed 16/32-bit Thumb-2 instructions based on the -mcpu=name and -march=name options.
-mtpcs-frame
Generate a stack frame that is compliant with the Thumb Procedure Call Standard for all non-leaf functions. (A leaf function is one that does not call any other functions.) The default is -mno-tpcs-frame.
-mtpcs-leaf-frame
Generate a stack frame that is compliant with the Thumb Procedure Call Standard for all leaf functions. (A leaf function is one that does not call any other functions.) The default is -mno-apcs-leaf-frame.
-mcallee-super-interworking
Gives all externally visible functions in the file being compiled an ARM instruction set header which switches to Thumb mode before executing the rest of the function. This allows these functions to be called from non-interworking code.
-mcaller-super-interworking
Allows calls via function pointers (including virtual functions) to execute correctly regardless of whether the target code has been compiled for interworking or not. There is a small overhead in the cost of executing a function pointer if this option is enabled.
-mtp=name
Specify the access model for the thread local storage pointer. The valid models are soft, which generates calls to __aeabi_read_tp, cp15, which fetches the thread pointer from cp15 directly (supported in the arm6k architecture), and auto, which uses the best available method for the selected processor. The default setting is auto.
-mword-relocations
Only generate absolute relocations on word sized values (i.e. R_ARM_ABS32). This is enabled by default on targets (uClinux, SymbianOS) where the runtime loader imposes this restriction, and when -fpic or -fPIC is specified.

<think>我们被要求使用arm-gcc编译器生成64位ARM架构的汇编代码。根据引用[1]和[2]的上下文,我们知道arm-linux-gccarm-none-eabi-gcc都是用于ARM架构的交叉编译器。但是,对于64位ARM(即AArch64),通常使用不同的工具链前缀。在64位ARM架构中,常用的交叉编译器前缀是`aarch64-linux-gnu-`。因此,编译64位ARM汇编代码应该使用`aarch64-linux-gnu-gcc`。步骤:1.安装针对AArch64的交叉编译工具链(如果尚未安装):在Ubuntu/Debian系统上,可以使用以下命令安装:```bashsudoapt-getinstallgcc-aarch64-linux-gnu```2.编写C代码(例如:test.c)或直接编写汇编代码。3.编译生成汇编代码(而不是目标文件或可执行文件):使用`-S`选项可以让编译器将C代码编译成汇编代码,然后停止。命令示例:```bashaarch64-linux-gnu-gcc-Stest.c-otest.s```这将生成一个64位ARM架构的汇编文件test.s。4.如果希望查看编译过程中的中间汇编代码(比如在编译优化后的汇编),可以添加优化选项,例如:```bashaarch64-linux-gnu-gcc-S-O2test.c-otest_optimized.s```5.如果已经有汇编代码文件(例如:source.S或source.s),想将其编译成可执行文件或目标文件,可以使用:```bashaarch64-linux-gnu-gcc-csource.S-osource.o```注意:汇编文件的扩展名使用大写`.S`表示需要预处理器处理(比如包含头文件等),小写`.s`表示不需要预处理器。6.如果要生成静态链接的可执行文件(使用静态库),可以加上`-static`选项,如引用[1]中所示:```bashaarch64-linux-gnu-gcc-statictest.c-otest```7.查看生成的汇编代码:使用文本编辑器打开生成的.s文件。示例C代码(test.c):```cintmain(){inta=1;intb=2;returna+b;}```生成的汇编代码(test.s)可能类似于:```assembly.archarmv8-a.file"test.c".text.section.text.startup,"ax",@progbits.align2.globalmain.typemain,%functionmain:movw0,3ret.sizemain,.-main.ident"GCC:(Ubuntu11.4.0-1ubuntu1~22.04)11.4.0".section.note.GNU-stack,"",@progbits```注意:由于优化,代码可能直接将结果3放入w0寄存器(ARM64中函数返回值通过w0寄存器传递)。如果用户希望从C代码生成汇编代码,那么上述步骤即可。如果用户希望直接编写64位ARM汇编代码,则只需将代码保存为.S或.s文件,然后用上述第5步编译。相关问题:1.如何安装AArch64交叉编译工具链?2.如何编写64位ARM汇编程序?3.如何将汇编代码与C代码混合编译?4.如何调试64位ARM汇编程序?</think>### 如何使用arm-gcc生成64位ARM汇编代码 要使用arm-gcc编译器生成64位ARM架构(AArch64)的汇编代码,请按照以下步骤操作: #### 1. 安装AArch64交叉编译工具链 ```bash # Ubuntu/Debian系统 sudo apt-get install gcc-aarch64-linux-gnu binutils-aarch64-linux-gnu # 验证安装 aarch64-linux-gnu-gcc --version ``` #### 2. 编译生成汇编代码 使用`-S`选项将C代码编译为汇编文件,并通过`-march`指定64位架构: ```bash aarch64-linux-gnu-gcc -S -O1 -march=armv8-a example.c -o output.s ``` **关键参数说明**: - `-S`:生成汇编代码而非可执行文件 - `-march=armv8-a`:指定ARMv8-A架构(64位) - `-O1`:基本优化级别(可选`-O0`关闭优化) #### 3. 查看生成的汇编代码 ```bash cat output.s ``` **示例输出**: ```armasm .arch armv8-a .file "example.c" .text .align 2 .global main .type main, %function main: sub sp, sp, #16 // 栈空间分配 mov w0, 0 // 32位寄存器操作 str wzr, [sp, 12] // 存储到栈 add sp, sp, 16 // 恢复栈指针 ret // 返回 .size main, .-main ``` #### 4. 编译选项对比 | 选项 | 32位ARM | 64位ARM | 作用 | |------|---------|---------|------| | 编译器 | `arm-linux-gnueabi-gcc` | `aarch64-linux-gnu-gcc` | 工具链选择 | | 架构 | `-march=armv7-a` | `-march=armv8-a` | 指令集指定 | | 寄存器 | w0-w15 (32位) | x0-x30 (64位) | 寄存器差异 | #### 5. 特殊场景处理 **混合32/64位编译**(需兼容模式): ```bash aarch64-linux-gnu-gcc -S -march=armv8-a+simd -mgeneral-regs-only example.c ``` **生成纯汇编文件**(无额外信息): ```bash aarch64-linux-gnu-gcc -S -fno-asynchronous-unwind-tables -fverbose-asm example.c ``` #### 验证工具 ```bash # 检查文件架构 file output.s # 输出:output.s: ASCII text, with assembler source code # 反汇编验证 aarch64-linux-gnu-objdump -d a.out ``` > **注意**:64位ARM使用AArch64指令集,寄存器为`x0-x30`(64位),其低32位可通过`w0-w30`访问。函数调用约定使用寄存器传递参数(x0-x7)[^1][^2]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值