如何为我的架构获取正确的二进制文件。尝试 运行 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

如果此答案中有什么地方不清楚,或者您认为您仍然缺少重要信息,请随时发表评论或相应地补充您的问题。