如何为我的架构获取正确的二进制文件。尝试 运行 ARM (.s) 文件
How to get the correct binary for my architecture. Trying to run ARM (.s) files
我在 ubuntu 到 运行 simple.s
上使用了以下命令进行交叉编译,但出现错误
> arm-linux-gnueabi-as -o simple.o simple.s
> arm-linux-gnueabi-ld -o simple simple.o
> ./simple
bash: ./simple: cannot execute binary file: Exec format error
> file simple
simple: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, not stripped
> uname -m
x86_64
命令是:
arm-linux-gnueabi-as -o simple.o simple.s
arm-linux-gnueabi-ld -o simple simple.o
./simple
我试图通过
获取二进制文件的架构
file simple
和我机器的架构
uname -m
发现他们不一样。我相信为架构获得正确的二进制文件将解决问题。是真的吗?
这里是simple.s
.global _start
@ comments start with the '@' character
@ the _start label is the entry point to the program
_start:
@ program code here
_exit:
@ it is usual to indent instructions with TAB
MOV R0, #65 @ arbitrary value
MOV R7, #1
SWI 0
如何解决这个问题?谢谢
您不能在 x86_64 Linux PC 上本机执行为 32 位 ARM Linux 系统编译的 Linux 可执行文件,因为使用由不同的公司,更重要的是,使用不同的指令集和不同的编程模型。
例如,如果用arm-linux-gnueabi-gcc
编译这个简单的C程序,编译器将生成如下ARM汇编代码:
add.c:
int add(int a, int b)
{
return a + b;
}
add.s:
.arch armv7-a
.file "add.c"
.text
.align 2
.global add
.arch armv7-a
.syntax unified
.arm
.fpu neon
.type add, %function
add:
@ args = 0, pretend = 0, frame = 8
@ frame_needed = 1, uses_anonymous_args = 0
@ link register save eliminated.
str fp, [sp, #-4]!
add fp, sp, #0
sub sp, sp, #12
str r0, [fp, #-8]
str r1, [fp, #-12]
ldr r2, [fp, #-8]
ldr r3, [fp, #-12]
add r3, r2, r3
mov r0, r3
add sp, fp, #0
@ sp needed
ldr fp, [sp], #4
bx lr
.size add, .-add
.ident "GCC: (GNU Toolchain for the A-profile Architecture 10.2-2020.11 (arm-10.16)) 10.2.1 20201103"
.section .note.GNU-stack,"",%progbits
现在,如果您使用 x86_64-linux-gnu-gcc
编译它,它将为 x86_64/amd64 架构生成代码:
add.s:
.file "add.c"
.text
.globl add
.type add, @function
add:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl %edi, -4(%rbp)
movl %esi, -8(%rbp)
movl -4(%rbp), %edx
movl -8(%rbp), %eax
addl %edx, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size add, .-add
.ident "GCC: (Debian 8.3.0-6) 8.3.0"
.section .note.GNU-stack,"",@progbits
如您所见,程序集完全不同,一旦它们被组装和链接,生成的机器代码也将完全不同。阅读标题为“长答案”的部分 here 会很明显。
不同的架构意味着不同的CPU:arm-linux-gnueabi-as
只能为ARM编译程序CPU没有硬件支持浮点运算运行Linux:编译器名称中有提示,它是根据体系结构、操作系统和 ABI 构建的,它可以为以下程序编译程序:
[arm]-[linux]-[gnueabi] 或 [x86_64]-[linux]-[gnu] 例如。
请参阅 here 了解简短说明
'target triplets' 在 gcc 编译器的上下文中。
Cross-compiling 是针对 CPU cpu#1 运行 操作系统 os#1 的计算机编译程序的操作CPU cpu#2 运行 操作系统 os#2.
的计算机
在您的例子中,您正在为 32 位 ARM CPU 运行 Linux 上的 运行 在 64 位 Intel CPU 上编译程序] (x86_64/amd64) 运行 Linux.
总线 cross-compiling 不允许 'cross-executing':为此,您需要使用 emulator such as qemu-arm
, either explicitly, or by using binfmt-support
as explained here。
如果此答案中有什么地方不清楚,或者您认为您仍然缺少重要信息,请随时发表评论或相应地补充您的问题。
我在 ubuntu 到 运行 simple.s
上使用了以下命令进行交叉编译,但出现错误
> arm-linux-gnueabi-as -o simple.o simple.s
> arm-linux-gnueabi-ld -o simple simple.o
> ./simple
bash: ./simple: cannot execute binary file: Exec format error
> file simple
simple: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, not stripped
> uname -m
x86_64
命令是:
arm-linux-gnueabi-as -o simple.o simple.s
arm-linux-gnueabi-ld -o simple simple.o
./simple
我试图通过
获取二进制文件的架构file simple
和我机器的架构
uname -m
发现他们不一样。我相信为架构获得正确的二进制文件将解决问题。是真的吗?
这里是simple.s
.global _start
@ comments start with the '@' character
@ the _start label is the entry point to the program
_start:
@ program code here
_exit:
@ it is usual to indent instructions with TAB
MOV R0, #65 @ arbitrary value
MOV R7, #1
SWI 0
如何解决这个问题?谢谢
您不能在 x86_64 Linux PC 上本机执行为 32 位 ARM Linux 系统编译的 Linux 可执行文件,因为使用由不同的公司,更重要的是,使用不同的指令集和不同的编程模型。
例如,如果用arm-linux-gnueabi-gcc
编译这个简单的C程序,编译器将生成如下ARM汇编代码:
add.c:
int add(int a, int b)
{
return a + b;
}
add.s:
.arch armv7-a
.file "add.c"
.text
.align 2
.global add
.arch armv7-a
.syntax unified
.arm
.fpu neon
.type add, %function
add:
@ args = 0, pretend = 0, frame = 8
@ frame_needed = 1, uses_anonymous_args = 0
@ link register save eliminated.
str fp, [sp, #-4]!
add fp, sp, #0
sub sp, sp, #12
str r0, [fp, #-8]
str r1, [fp, #-12]
ldr r2, [fp, #-8]
ldr r3, [fp, #-12]
add r3, r2, r3
mov r0, r3
add sp, fp, #0
@ sp needed
ldr fp, [sp], #4
bx lr
.size add, .-add
.ident "GCC: (GNU Toolchain for the A-profile Architecture 10.2-2020.11 (arm-10.16)) 10.2.1 20201103"
.section .note.GNU-stack,"",%progbits
现在,如果您使用 x86_64-linux-gnu-gcc
编译它,它将为 x86_64/amd64 架构生成代码:
add.s:
.file "add.c"
.text
.globl add
.type add, @function
add:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl %edi, -4(%rbp)
movl %esi, -8(%rbp)
movl -4(%rbp), %edx
movl -8(%rbp), %eax
addl %edx, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size add, .-add
.ident "GCC: (Debian 8.3.0-6) 8.3.0"
.section .note.GNU-stack,"",@progbits
如您所见,程序集完全不同,一旦它们被组装和链接,生成的机器代码也将完全不同。阅读标题为“长答案”的部分 here 会很明显。
不同的架构意味着不同的CPU:arm-linux-gnueabi-as
只能为ARM编译程序CPU没有硬件支持浮点运算运行Linux:编译器名称中有提示,它是根据体系结构、操作系统和 ABI 构建的,它可以为以下程序编译程序:
[arm]-[linux]-[gnueabi] 或 [x86_64]-[linux]-[gnu] 例如。 请参阅 here 了解简短说明 'target triplets' 在 gcc 编译器的上下文中。
Cross-compiling 是针对 CPU cpu#1 运行 操作系统 os#1 的计算机编译程序的操作CPU cpu#2 运行 操作系统 os#2.
的计算机在您的例子中,您正在为 32 位 ARM CPU 运行 Linux 上的 运行 在 64 位 Intel CPU 上编译程序] (x86_64/amd64) 运行 Linux.
总线 cross-compiling 不允许 'cross-executing':为此,您需要使用 emulator such as qemu-arm
, either explicitly, or by using binfmt-support
as explained here。
如果此答案中有什么地方不清楚,或者您认为您仍然缺少重要信息,请随时发表评论或相应地补充您的问题。