请为arm926ejs cpu使用gnu汇编器帮助我.
我尝试构建一个简单的程序(test.S):
.global _start
_start:
mov r0, #2
bx lr
并成功构建它:
arm-none-linux-gnueabi-as -mthumb -o test.o test.S
arm-none-linux-gnueabi-ld -o test test.o
但是当我在arm目标linux环境中运行程序时,出现错误:
./test
Segmentation fault
我究竟做错了什么?
_start函数可以用作拇指功能吗?
要么
总是手臂功能吗?
解决方法:
Can _start be a thumb function (in a Linux user program)?
是的,它可以.步骤并不像您想象的那么简单.
请按照其他人的描述使用.code 16.再看ARM Script predicate;我的答案显示了如何检测拇指二进制文件.入口符号必须具有传统的_start 1值,否则Linux将决定以ARM模式调用_start.
您的代码也在尝试模仿,
int main(void) { return 2; }
_start符号不能这样做(按照auselen).要在ARM模式下对main进行_start操作,
#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! */
);
}
最好清除lr以便终止堆栈跟踪.如果需要,可以避免argc和argv处理.开头显示了如何使用它. estart只是将main()返回代码转换为exit()调用的包装器.
您需要将上述汇编程序转换为Thumb等效项.我建议使用gcc内联汇编程序.如果可以使用内联代码,则可以转换为纯汇编程序源.但是,除非您试图制作一个非常小的可执行文件,否则在“ C”源代码中这样做可能更实际.
有用的gcc争论是,
-nostartfiles -static -nostdlib -isystem <path to linux user headers>
添加-mthumb,您应该具有用于这两种模式的工具.