car*_*ass 0 c assembly program-entry-point x86-64
请注意,这个问题在这里已经有类似的答案,我想指出:
然而,这个问题更多地询问它们的返回格式以及它们如何相互关联(我认为上面的问题没有完全涵盖)。
_start和之间有什么区别main?在我看来,像ld用途_start,但gcc用途main为切入点。我注意到的另一个区别是main似乎返回值 in %rax,而_start返回值 in%rbx
以下是我看到的两种方式的示例:
.globl _start
_start:
mov $1, %rax
mov $2, %rbx
int $0x80
Run Code Online (Sandbox Code Playgroud)
并运行它:
$ as script.s -o script.o; ld script.o -o script; ./script; echo $?
# 2
Run Code Online (Sandbox Code Playgroud)
另一种方式:
.globl main
main:
mov $3, %rax
ret
Run Code Online (Sandbox Code Playgroud)
并运行它:
$ gcc script.s -o script; ./script; echo $?
3
Run Code Online (Sandbox Code Playgroud)
这两种方法有什么区别?是否main自动调用_start某处,或者它们如何相互关联?为什么一个返回它们的值,rbx而另一个返回它的值rax?
TL:DR:函数返回值和系统调用参数使用单独的寄存器,因为它们完全不相关。
当您使用 编译时gcc,它会链接 CRT 启动代码,该代码定义了一个_start. 那_start(间接)调用main,并将main的返回值(主要留在 EAX 中)传递给exit()库函数。(在执行任何必要的 libc 清理(如刷新 stdio 缓冲区)之后,最终会进行退出系统调用。)
另请参阅从 C 中的 main 函数返回与退出- 这与您正在执行的操作完全相似,除了您使用的_exit()是绕过 libc 清理的exit(). exit() 的系统调用实现
根据int $0x8032 位系统调用 ABI(您不应在 64 位代码中使用),系统调用在 EBX 中采用其参数。 它不是函数的返回值,而是进程退出状态。看到带有 Linux 系统调用的汇编语言中的 Hello, world 吗?有关系统调用的更多信息。
请注意,这_start不是一个函数;它不能从这个意义上返回,因为堆栈上没有返回地址。 您正在采用诸如“返回操作系统”之类的随意描述并将其与函数的“返回值”混为一谈。 你可以打电话exit从main,如果你想要的,但你不能ret从_start。
EAX 是int函数调用约定中大小值的返回值寄存器。(RAX的高32位被忽略,因为main回报率int。但同时,$?退出状态只能得到低传给值的8位exit())。
有关的:
syscall,并展示了系统调用后内核内部发生的事情的一些内核方面。| 归档时间: |
|
| 查看次数: |
278 次 |
| 最近记录: |