_start可以是thumb函数吗?

请为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,您应该具有用于​​这两种模式的工具.

上一篇:ARM体系结构与编程-第六章


下一篇:小程序 模拟今日头条导航栏,点击锚点跳转对应楼层