_start 可以是拇指函数吗?

2023-12-14

请帮助我使用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 函数可以是拇指函数吗? 或者 它总是手臂功能?


_start 可以是一个拇指函数(在 Linux 用户程序中)吗?

是的,它可以。步骤并不像您想象的那么简单。

请使用.code 16正如其他人所描述的。还看ARM 脚本谓词;我的答案显示了如何检测thumb二进制。条目符号必须具有传统的_start+1值或 Linux 将决定调用您的_start in ARM mode.

您的代码也试图模拟,

 int main(void) { return 2; }

The _start符号不得执行此操作(根据auselen)。去做_start to main() in ARM您需要的模式,

 #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 and argv如果你愿意的话可以处理。这start展示了如何使用它。这estart只是一个包装器来转换main()返回代码到exit() call.

您需要将上面的汇编程序转换为Thumb等价物。我建议使用gcc 内联汇编器。如果内联可以工作,您可以转换为纯汇编源。然而,在“C”源代码中执行此操作可能更实用,除非您试图创建一个非常小的可执行文件。

Helpful gcc论据是,

 -nostartfiles -static -nostdlib -isystem <path to linux user headers>

Add -mthumb并且您应该有适合任一模式的安全带。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

_start 可以是拇指函数吗? 的相关文章

随机推荐