可以_start是拇指的功能? [英] Can _start be the thumb function?
问题描述
请帮助我与ARM926EJS CPU GNU汇编。
我尝试建立一个简单的程序(test.S):
。全球_start
_开始:
MOV R0,#2
BX LR
和成功构建它:
ARM-NONE-Linux的gnueabi-作为-mthumb -o test.o test.S
臂无-Linux的gnueabi-LD -o测试test.o
但是当我运行在ARM目标linux环境下的程序,我得到一个错误:
./测试
分段故障
我是什么做错了吗?
_start功能可以将拇指FUNC?
要么
它总是手臂FUNC?
能否_Start是一个拇指功能(在Linux用户程序)?
块引用>是的,它可以。这些步骤并不像你可能认为的那么简单。
请使用
code 16
为他人介绍。还看<一个href=\"http://stackoverflow.com/questions/15913964/script-tool-$p$pdicate-for-arm-elf-compiled-for-thumb-or-arm\">ARM脚本predicate ;我的回答显示了如何检测的拇指的二进制文件。入口标志必须具备传统_start + 1
值或Linux将决定打电话给你的_start
在 ARM 模式。此外,您的code为试图效仿,
INT主要(无效){返回2; }
的
_start
符号必须不能做到这一点(按照 auselen )。要做到_start
到的main()
在 ARM 模式下,你所需要的,的#include&LT; Linux的/ unistd.h中&GT;
静态内嵌无效退出(INT状态)
{
ASM挥发性(MOV R0,%0 \\ n \\ t的
MOV R7,%1 \\ n \\ t的
SWI#7 \\ n \\ t的
:R(状态),
IR(__NR_exit)
:R0,R 7);
}
/ *包装主返回code。 * /
无效__attribute__((未使用))estart(INT ARGC,CHAR *的argv [])
{
INT RVAL =主(ARGC,ARGV);
出口(RVAL);
} / *为estart设置参数[形主()。 * /
无效__attribute__((裸体))_start(无效)
{
ASM(子LR,LR,LR \\ n/ *清除链接寄存器。* /
LDR R0,[SP] \\ n/ *获取的argc ... * /
ADD R1,SP,#4 \\ n/ * ...和argv ... * /
B estart \\ n/ *走吧! * /
);
}这是很好的清除
LR
这样的堆栈跟踪将被终止。你能避免,如果你想在ARGC
和的argv
处理。在启动
显示了如何使用这项工作。在estart
只是一个包装转换的的main()
收益code到退出()
电话。您需要将上面的汇编程序转换为拇指当量。我会建议使用的 GCC内联汇编的。你可以转换为纯汇编源代码,如果你得到内联工作。然而,在'C'源这样可能更实用,除非你是试图使一个很小的可执行文件。
有用的的gcc 的arguements是,
-nostartfiles -static -nostdlib -isystem&LT;路径Linux用户头&GT;
添加
-mthumb
,你应该有两种模式下线束。Help me please with gnu assembler for arm926ejs cpu.
I try to build a simple program(test.S):
.global _start _start: mov r0, #2 bx lr
and success build it:
arm-none-linux-gnueabi-as -mthumb -o test.o test.S arm-none-linux-gnueabi-ld -o test test.o
but when I run the program in the arm target linux environment, I get an error:
./test Segmentation fault
What am I doing wrong? Can _start function be the thumb func? or It is always arm func?
解决方案Can _start be a thumb function (in a Linux user program)?
Yes it can. The steps are not as simple as you may believe.
Please use the
.code 16
as described by others. Also look at ARM Script predicate; my answer shows how to detect a thumb binary. The entry symbol must have the traditional_start+1
value or Linux will decide to call your_start
in ARM mode.Also your code is trying to emulate,
int main(void) { return 2; }
The
_start
symbol must not do this (as per auselen). To do_start
tomain()
in ARM mode you need,#include <linux/unistd.h> static inline void exit(int status) { asm volatile ("mov r0, %0\n\t" "mov r7, %1\n\t" "swi #7\n\t" : : "r" (status), "Ir" (__NR_exit) : "r0", "r7"); } /* Wrapper for main return code. */ void __attribute__ ((unused)) estart (int argc, char*argv[]) { int rval = main(argc,argv); exit(rval); } /* Setup arguments for estart [like main()]. */ void __attribute__ ((naked)) _start (void) { asm(" sub lr, lr, lr\n" /* Clear the link register. */ " ldr r0, [sp]\n" /* Get argc... */ " add r1, sp, #4\n" /* ... and argv ... */ " b estart\n" /* Let's go! */ ); }
It is good to clear the
lr
so that stack traces will terminate. You can avoid theargc
andargv
processing if you want. Thestart
shows how to work with this. Theestart
is just a wrapper to convert themain()
return code to anexit()
call.You need to convert the above assembler to Thumb equivalents. I would suggest using gcc inline assembler. You can convert to pure assembler source if you get inlines to work. However, doing this in 'C' source is probably more practical, unless you are trying to make a very minimal executable.
Helpful gcc arguements are,
-nostartfiles -static -nostdlib -isystem <path to linux user headers>
Add
-mthumb
and you should have a harness for either mode.这篇关于可以_start是拇指的功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!