如果您要查看标准装配,主要调用正常功能,之后将ret和sfp放入堆栈等?有一个巨大的objdump,我认为这是它必须的方式,因为init和东西发生在main之前,对吗?
答案 0 :(得分:3)
程序中的实际入口点是以特定于操作系统的方式启动的。我相信在Windows上你得到一个返回地址,所以它被称为。例如,在Linux中,您无法使用ret
来结束您的程序。
如果你说的是C main
函数,那么你应该知道它不是程序的入口点,因为它存在于C库启动代码中,它确实会调用你的{{1 }}
答案 1 :(得分:0)
如果您使用的是8086汇编程序,那么" main"只是一个带有任何名称的标签,有些人称之为"开始"或"开始"。编译器知道它是起点,因为在代码的末尾添加" end main"或者"结束开始"。
在接下来的例子中," main"或者"开始"是起点,所以数据段的初始化永远不会被执行,因为它在" main" /"开始"之前。标签
因为"主要" /"开始"不是程序,他们不需要RET,因为他们从来没有打过电话"电话"指令(堆栈上没有返回地址)。这就是为什么用ax = 4c00h int 21h:
来结束程序的原因.stack 100h
.data
.code
;INITIALIZE DATA SEGMENT.
mov ax,@data
mov ds,ax
main: ;<======================
xor ax, ax
;FINISH THE PROGRAM.
mov ax,4c00h
int 21h
end main ;<======================
或者&#34;开始&#34; :
.stack 100h
.data
.code
;INITIALIZE DATA SEGMENT.
mov ax,@data
mov ds,ax
begin: ;<======================
xor ax, ax
;FINISH THE PROGRAM.
mov ax,4c00h
int 21h
end begin ;<======================
如果代码没有包含&#34;结束主&#34; /&#34;结束开始&#34;指令,起点将是&#34;代码&#34; label(代码段开始的地方)。
答案 2 :(得分:0)
行为取决于上下文,如果你的代码在windows上运行,例如,“main”是入口点,并在进程启动后由os调用,并且确实有一个地址返回到程序时结束,它还读取EAX作为退出代码
以下是Windows调用入口点时的样子
/. 55 PUSH EBP
|. 8BEC MOV EBP,ESP
|. 85C9 TEST ECX,ECX
|. 75 0C JNZ SHORT KERNEL32.7672A53B
|. FF75 08 PUSH DWORD PTR SS:[EBP+8]
|. FFD2 CALL EDX <- Program entry point is called
|. 50 PUSH EAX
|. FF15 B4117976 CALL DWORD PTR DS:[<&ntdll.RtlExitUserTh>; ntdll.RtlExitUserThread
|> F605 D002FE7F >TEST BYTE PTR DS:[7FFE02D0],10
|. 74 09 JE SHORT KERNEL32.7672A54D
|. E8 0F000000 CALL KERNEL32.7672A558
|. 85C0 TEST EAX,EAX
|. 78 02 JS SHORT KERNEL32.7672A54F
|> 33C0 XOR EAX,EAX
|> 5D POP EBP
\. C2 0400 RETN 4