Assembly 试图将.c文件与.s文件链接,但我得到;“非法指令”;
我有两个文件,9-main.c和9-mult.s 9-main.c:Assembly 试图将.c文件与.s文件链接,但我得到;“非法指令”;,assembly,gcc,linker,arm,illegal-instruction,Assembly,Gcc,Linker,Arm,Illegal Instruction,我有两个文件,9-main.c和9-mult.s 9-main.c: #include <stdio.h> int mult(int); int main(){ int result = mult(5); printf("Result: %d\n",result); return 0; } .global mult mult: mov r1,r0 lsl r0,
#include <stdio.h>
int mult(int);
int main(){
int result = mult(5);
printf("Result: %d\n",result);
return 0;
}
.global mult
mult:
mov r1,r0
lsl r0,r0,#4
add r0,r1,r0
bx lr
我试图将它们联系起来:
$ arm-linux-gnueabihf-gcc 9-main.c 9-mult.s
但如果我执行a.out:
$ ./a.out
Illegal instruction
原因可能是什么?对于初学者来说,您正在一个非常复杂的环境中编译/执行:在
aarch64
系统上编译/链接/执行aarch32
C/汇编代码的混合
我建议您开始指定要组装的体系结构以及要使用的确切指令集-这对于想要帮助的人来说是有用的信息-并使用一些标准指令将GNU中的函数定义为汇编语言,就像gcc编译器生成函数的方式一样:
.arch armv7-a // target architecture is armv7-a/Aarch32
.fpu vfpv3-d16 // specify available floating-point hardware
.syntax unified // use unified assembler syntax
.arm // generate 32 bit Arm code
.type mult, %function // 'mult' symbol is related to a function
.global mult // 'mult' is a global symbol
.text // code will be put into the .text section
mult:
mov r1,r0
lsl r0,r0,#4
add r0,r1,r0
bx lr
.end // end of program
./a.out
Result: 85
有关详细信息,请参阅
我仍在寻找问题的根本原因,该问题实际上已通过使用修复。键入mult,%function
。请注意,在Cortex-A7
Linux系统上确实会发生完全相同的错误,这是因为运行64位Linux的用户不是问题所在
编译两个可执行文件(带/不带.type指令)并比较readelf-a
命令的输出仅显示一个区别:
267c267
< 104: 00000534 0 NOTYPE GLOBAL DEFAULT 13 mult
---
> 104: 00000534 0 FUNC GLOBAL DEFAULT 13 mult
另一个选项是强制GNU AS以mult.s格式生成thumb2/T32代码:
.thumb
.global mult
mult:
mov r1,r0
lsl r0,r0,#4
add r0,r1,r0
bx lr
arm-linux-gnueabihf-gcc-10 -g -o mult mult.c mult.s
./mult
Result: 85
有关thumb2/T32、arm/A32和interwork代码的更多详细信息,请参阅和。对于初学者来说,您正在一个非平凡的环境中编译/执行:在
aarch64
系统上编译/链接/执行aarch32
C/汇编代码的混合
我建议您开始指定要组装的体系结构以及要使用的确切指令集-这对于想要帮助的人来说是有用的信息-并使用一些标准指令将GNU中的函数定义为汇编语言,就像gcc编译器生成函数的方式一样:
.arch armv7-a // target architecture is armv7-a/Aarch32
.fpu vfpv3-d16 // specify available floating-point hardware
.syntax unified // use unified assembler syntax
.arm // generate 32 bit Arm code
.type mult, %function // 'mult' symbol is related to a function
.global mult // 'mult' is a global symbol
.text // code will be put into the .text section
mult:
mov r1,r0
lsl r0,r0,#4
add r0,r1,r0
bx lr
.end // end of program
./a.out
Result: 85
有关详细信息,请参阅
我仍在寻找问题的根本原因,该问题实际上已通过使用修复。键入mult,%function
。请注意,在Cortex-A7
Linux系统上确实会发生完全相同的错误,这是因为运行64位Linux的用户不是问题所在
编译两个可执行文件(带/不带.type指令)并比较readelf-a
命令的输出仅显示一个区别:
267c267
< 104: 00000534 0 NOTYPE GLOBAL DEFAULT 13 mult
---
> 104: 00000534 0 FUNC GLOBAL DEFAULT 13 mult
另一个选项是强制GNU AS以mult.s格式生成thumb2/T32代码:
.thumb
.global mult
mult:
mov r1,r0
lsl r0,r0,#4
add r0,r1,r0
bx lr
arm-linux-gnueabihf-gcc-10 -g -o mult mult.c mult.s
./mult
Result: 85
有关thumb2/T32、arm/A32和互通代码的更多详细信息,请参阅和。您确实需要获取arm文档并学习指令集 你应该反汇编你的程序来确认。第一个问题是,您是否在x86上交叉编译此代码,然后尝试在x86上运行ARM?我想你会得到一个不同的错误。接下来是一个a.out文件格式问题,这可能是原始的,因此尝试在aarch64模式下运行aarch32将是错误的指令或 对于64位arm(armv8…)上的armv7兼容模式,如果告知或为此而构建,gcc编译器将默认为thumb/thumb2模式
int mult(int);
int fun ( void )
{
return(mult(5)+1);
}
00000000 <fun>:
0: e96d 3e02 strd r3, lr, [sp, #-8]!
4: f04f 0005 mov.w r0, #5
8: f7ff fffe bl 0 <mult>
c: f100 0001 add.w r0, r0, #1
10: bd08 pop {r3, pc}
12: bf00 nop
将默认为arm,除非在命令行上另有指定(实际上并非如此)
告诉工具mult是一个功能标签,重新组装并重新链接:
00002000 <fun>:
2000: e96d 3e02 strd r3, lr, [sp, #-8]!
2004: f04f 0005 mov.w r0, #5
2008: f000 e804 blx 2014 <mult>
200c: f100 0001 add.w r0, r0, #1
2010: bd08 pop {r3, pc}
2012: bf00 nop
00002014 <mult>:
2014: e1a01000 mov r1, r0
2018: e1a00200 lsl r0, r0, #4
201c: e0810000 add r0, r1, r0
2020: e12fff1e bx lr
当您学习asm时,甚至有时不学习asm时,如果您正在混合语言,您应该始终遵循以下原则:
arm-linux-gnueabihf-objdump -D myprog.elf
并检查输出
可以仅对代码使用小写-d,大写-d还将包括数据部分,这些数据部分通常与您希望它构建的内容一样重要
为了完成提问,我建议您分解并发布main函数和mult函数,看看这是否是一个互通问题。或者您尝试在x86或类似的机器上运行arm二进制文件
如果您检查编译器的完整输出,Frant显示了一组更详细的指令
.cpu cortex-a72
.eabi_attribute 20, 1
.eabi_attribute 21, 1
.eabi_attribute 23, 3
.eabi_attribute 24, 1
.eabi_attribute 25, 1
.eabi_attribute 26, 1
.eabi_attribute 30, 2
.eabi_attribute 34, 1
.eabi_attribute 18, 4
.file "so.c"
.text
.align 1
.p2align 2,,3
.global fun
.arch armv8-a
.arch_extension crc
.syntax unified
.thumb
.thumb_func
.fpu softvfp
.type fun, %function
fun:
@ args = 0, pretend = 0, frame = 0
@ frame_needed = 0, uses_anonymous_args = 0
strd r3, lr, [sp, #-8]!
mov r0, #5
bl mult
add r0, r0, #1
pop {r3, pc}
.size fun, .-fun
.ident "GCC: (GNU) 10.2.0"
除其他外,您将看到.type函数。他们在这里双浸入,同时执行.type和.thumb_func,这是一个算法驱动的输出。您确实需要获得arm文档并学习指令集 你应该反汇编你的程序来确认。第一个问题是,您是否在x86上交叉编译此代码,然后尝试在x86上运行ARM?我想你会得到一个不同的错误。接下来是一个a.out文件格式问题,这可能是原始的,因此尝试在aarch64模式下运行aarch32将是错误的指令或 对于64位arm(armv8…)上的armv7兼容模式,如果告知或为此而构建,gcc编译器将默认为thumb/thumb2模式
int mult(int);
int fun ( void )
{
return(mult(5)+1);
}
00000000 <fun>:
0: e96d 3e02 strd r3, lr, [sp, #-8]!
4: f04f 0005 mov.w r0, #5
8: f7ff fffe bl 0 <mult>
c: f100 0001 add.w r0, r0, #1
10: bd08 pop {r3, pc}
12: bf00 nop
将默认为arm,除非在命令行上另有指定(实际上并非如此)
告诉工具mult是一个功能标签,重新组装并重新链接:
00002000 <fun>:
2000: e96d 3e02 strd r3, lr, [sp, #-8]!
2004: f04f 0005 mov.w r0, #5
2008: f000 e804 blx 2014 <mult>
200c: f100 0001 add.w r0, r0, #1
2010: bd08 pop {r3, pc}
2012: bf00 nop
00002014 <mult>:
2014: e1a01000 mov r1, r0
2018: e1a00200 lsl r0, r0, #4
201c: e0810000 add r0, r1, r0
2020: e12fff1e bx lr
当您学习asm时,甚至有时不学习asm时,如果您正在混合语言,您应该始终遵循以下原则:
arm-linux-gnueabihf-objdump -D myprog.elf
并检查输出
可以仅对代码使用小写-d,大写-d还将包括数据部分,这些数据部分通常与您希望它构建的内容一样重要
为了完成提问,我建议您分解并发布main函数和mult函数,看看这是否是一个互通问题。或者您尝试在x86或类似的机器上运行arm二进制文件
如果您检查编译器的完整输出,Frant显示了一组更详细的指令
.cpu cortex-a72
.eabi_attribute 20, 1
.eabi_attribute 21, 1
.eabi_attribute 23, 3
.eabi_attribute 24, 1
.eabi_attribute 25, 1
.eabi_attribute 26, 1
.eabi_attribute 30, 2
.eabi_attribute 34, 1
.eabi_attribute 18, 4
.file "so.c"
.text
.align 1
.p2align 2,,3
.global fun
.arch armv8-a
.arch_extension crc
.syntax unified
.thumb
.thumb_func
.fpu softvfp
.type fun, %function
fun:
@ args = 0, pretend = 0, frame = 0
@ frame_needed = 0, uses_anonymous_args = 0
strd r3, lr, [sp, #-8]!
mov r0, #5
bl mult
add r0, r0, #1
pop {r3, pc}
.size fun, .-fun
.ident "GCC: (GNU) 10.2.0"
除其他外,您将看到.type函数。他们在这里双击并执行.type和.thumb_func,这是一个算法驱动的输出。我假设您试图在目标系统上运行该程序?如果在调试器中运行,它会在哪里停止?您的汇编代码看起来像拇指代码。你的C代码是什么
arm-linux-gnueabihf-objdump -D myprog.elf
.cpu cortex-a72
.eabi_attribute 20, 1
.eabi_attribute 21, 1
.eabi_attribute 23, 3
.eabi_attribute 24, 1
.eabi_attribute 25, 1
.eabi_attribute 26, 1
.eabi_attribute 30, 2
.eabi_attribute 34, 1
.eabi_attribute 18, 4
.file "so.c"
.text
.align 1
.p2align 2,,3
.global fun
.arch armv8-a
.arch_extension crc
.syntax unified
.thumb
.thumb_func
.fpu softvfp
.type fun, %function
fun:
@ args = 0, pretend = 0, frame = 0
@ frame_needed = 0, uses_anonymous_args = 0
strd r3, lr, [sp, #-8]!
mov r0, #5
bl mult
add r0, r0, #1
pop {r3, pc}
.size fun, .-fun
.ident "GCC: (GNU) 10.2.0"