如何为我的体系结构获得正确的二进制文件.试图运行ARM (.s)文件



我使用以下命令在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

如何解决这个问题?Thx

不能在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;
}

。:

.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体系结构的代码:

。:

.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

可以看到,程序集是完全不同的,一旦它们被组装和链接,生成的机器码也将是完全不同的。阅读标题为">长篇大论"的部分会让你更清楚。

不同的体系结构意味着不同的CPU:arm-linux-gnueabi-as只能在没有硬件支持的ARM CPU上编译程序,在Linux上运行浮点运算:编译器的名称中有一个提示,它是从体系结构,操作系统和ABI中构建的,它可以编译程序:

(手臂)- (linux) [gnueabi]或[x86_64] - (linux) (gnu)为例。请看这里的简短解释在GCC编译器的上下文中'目标三元组'是什么。

交叉编译是指在一台CPU #1运行os#1操作系统的计算机上,在另一台CPU #2运行os#2操作系统的计算机上编译一个程序的操作。

在你的例子中,你正在编译一个在运行Linux的32位ARM CPU上运行的程序,在运行Linux的64位Intel CPU (x86_64/amd64)上运行。

总线交叉编译不允许"交叉执行":要做到这一点,你需要使用一个模拟器,比如qemu-arm,要么显式地使用,要么像这里解释的那样使用binfmt-support

如果在这个答案中有什么不清楚的地方,或者如果你认为你仍然遗漏了一个关键的信息,请随意评论或相应补充你的问题。

相关内容

  • 没有找到相关文章

最新更新