_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
并且您应该有适合任一模式的安全带。