C 返回主vs_start中的值
注意,这个问题在这里已经有了类似的答案,我想指出:C 返回主vs_start中的值,c,assembly,x86-64,main,C,Assembly,X86 64,Main,注意,这个问题在这里已经有了类似的答案,我想指出: 然而,这个问题更多地询问了它们的返回格式以及它们之间的关系(我认为上面的问题并没有完全涉及到这一点) \u start和main之间有什么区别?在我看来,ld使用\u start,但是gcc使用main作为入口点。我注意到的另一个区别是,main似乎返回%rax中的值,而\u start返回%rbx中的值 以下是我看到这一点的两种方式的示例: .globl _start _start: mov $1, %rax mov
\u start
和main
之间有什么区别?在我看来,ld
使用\u start
,但是gcc
使用main
作为入口点。我注意到的另一个区别是,main
似乎返回%rax
中的值,而\u start
返回%rbx
中的值
以下是我看到这一点的两种方式的示例:
.globl _start
_start:
mov $1, %rax
mov $2, %rbx
int $0x80
要运行它:
$ as script.s -o script.o; ld script.o -o script; ./script; echo $?
# 2
$ gcc script.s -o script; ./script; echo $?
3
另一方面:
.globl main
main:
mov $3, %rax
ret
要运行它:
$ as script.s -o script.o; ld script.o -o script; ./script; echo $?
# 2
$ gcc script.s -o script; ./script; echo $?
3
这两种方法有什么区别?
main
是否会在某个地方自动调用\u start
,或者它们之间的关系如何?为什么一个在rbx
中返回值,而另一个在rax
中返回值?TL:DR:函数返回值和系统调用参数使用单独的寄存器,因为它们完全不相关
当您使用
gcc
进行编译时,它会链接定义\u start
的CRT启动代码该\u start
(间接)调用main
,并将main
的返回值(main留在EAX中)传递给exit()
库函数。(在执行任何必要的libc清理(如刷新stdio缓冲区)后,它最终会发出一个退出系统调用。)
另请参见-这与您所做的完全类似,只是您使用的是绕过libc清理的\u exit()
,而不是exit()
根据32位系统调用ABI()在EBX中获取其参数它不是函数的返回值,而是进程退出状态。有关系统调用的更多信息,请参阅
请注意,\u start
不是一个函数;从这个意义上讲,它不能返回,因为堆栈上没有返回地址您正在采用一种随意的描述,如“返回操作系统”,并将其与函数的“返回值”混为一谈。如果需要,您可以从main
调用exit
,但不能从\start
调用ret
EAX是函数调用约定中int
大小的值的返回值寄存器。(RAX的高32位被忽略,因为main
返回int
。但是,$?
退出状态只能获得传递给exit()
的值的低8位)
相关的:
- 解释为什么应该使用
,并显示系统调用后内核内部发生的一些内核方面的情况syscall
Disassembly of section .init:
00000000000004b8 <_init>:
4b8: 48 83 ec 08 sub $0x8,%rsp
4bc: 48 8b 05 25 0b 20 00 mov 0x200b25(%rip),%rax # 200fe8 <__gmon_start__>
4c3: 48 85 c0 test %rax,%rax
4c6: 74 02 je 4ca <_init+0x12>
4c8: ff d0 callq *%rax
4ca: 48 83 c4 08 add $0x8,%rsp
4ce: c3 retq
...
Disassembly of section .text:
00000000000004f0 <main>:
4f0: b8 05 00 00 00 mov $0x5,%eax
4f5: c3 retq
4f6: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
4fd: 00 00 00
...
0000000000000500 <_start>:
500: 31 ed xor %ebp,%ebp
502: 49 89 d1 mov %rdx,%r9
505: 5e pop %rsi
506: 48 89 e2 mov %rsp,%rdx
509: 48 83 e4 f0 and $0xfffffffffffffff0,%rsp
50d: 50 push %rax
50e: 54 push %rsp
50f: 4c 8d 05 6a 01 00 00 lea 0x16a(%rip),%r8 # 680 <__libc_csu_fini>
516: 48 8d 0d f3 00 00 00 lea 0xf3(%rip),%rcx # 610 <__libc_csu_init>
51d: 48 8d 3d cc ff ff ff lea -0x34(%rip),%rdi # 4f0 <main>
524: ff 15 b6 0a 20 00 callq *0x200ab6(%rip) # 200fe0 <__libc_start_main@GLIBC_2.2.5>
52a: f4 hlt
52b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)