简体   繁体   English

“呼叫___main”有什么作用?

[英]What does "call ___main" do?

When I compile Fortran or FreeBASIC code into assembly, the instruction当我将 Fortran 或 FreeBASIC 代码编译成汇编时,指令

call ___main

is found in the assembly code generated by the compiler.在编译器生成的汇编代码中找到。

However, when I use cl.exe to compile C++ code, this instruction is not generated by the compiler.但是,当我使用 cl.exe 编译 C++ 代码时,编译器不会生成这条指令。

Both Fortran and FreeBASIC does not contain a function called ___main , how is this function automatically generated? Fortran 和 FreeBASIC 都不包含名为___main的 function ,这个 function 是如何自动生成的?

Since we usually have done a good job of initialization in the BOOTLOADER, including code handling, we had better not call the library function __main(), because __main(), as a library function integrated with ADS, will initialize the system, which may conflict with our initialization.由于我们通常在 BOOTLOADER 中已经做好了初始化工作,包括代码处理,所以最好不要调用库 function __main(),因为 __main() 作为集成了 ADS 的库 function 会初始化系统,这可能与我们的初始化冲突。 So it's best not to call __main() after we've initialized it.所以在我们初始化之后最好不要调用 __main() 。 When simulation, if __main() is adjusted and entry is not set, a warning will be given.模拟的时候,如果调整了__main(),没有设置entry,会给出警告。 The __main() library function code is not well understood. __main() 库 function 代码不太好理解。 It is estimated that the library function __main() should be used carefully.估计要小心使用库function __main()。

When all the system initialization is complete, you need to transfer the program flow to the main application, that is, call the main application.当所有系统初始化完成后,需要将程序流程转移到主应用程序,即调用主应用程序。 The simplest case is:最简单的情况是:

IMPORT main进口主要

B main乙主

Jump directly from the startup code to the main function entry of the application, though the main function name can be arbitrarily defined by the user.直接从启动代码跳转到应用程序的主 function 入口,虽然主 function 名称可以由用户任意定义。

In the ARM ADS environment, there is an additional set of system-level calling mechanisms.在 ARM ADS 环境中,还有一组额外的系统级调用机制。

IMPORT __main导入 __main

B __main B __main

__main() is a function provided by the build system that initializes library functions and initializes the application execution environment, and then automatically jumps to main(). __main()是构建系统提供的一个function,初始化库函数,初始化应用执行环境,然后自动跳转到main()。 So, the first is a library function, and the second is our own main() function;所以,第一个是库function,第二个是我们自己的main() function;

So we use B __main to actually execute a library function, which then calls our main() function, so when you step through it you'll see that you have to run a section of the program (which is actually a library function), and then step through to our own main function (this also means that if you have B __main If we use B main to enter our main function, we will see our own main function directly in the step, no other program in between;所以我们使用 B __main 来实际执行一个库 function,然后调用我们的 main() function,所以当你单步执行它时,你会看到你必须运行程序的一部分(这实际上是一个库函数),然后单步进入到我们自己的主function(这也意味着如果你有B __main 如果我们用B主进入我们的主function,我们会看到我们自己的主ZC1C425268E68385D1AB5074F14F14之间直接在;

So what's the difference between using B __main and using B main what's the difference between entering our main function?那么使用 B __main 和使用 B main 有什么区别呢?进入我们的 main function 有什么区别呢?

If the former is used, the compiler will add a "segment copy" program, that is, we say from the load domain to the execution domain conversion program;如果使用前者,编译器会添加一个“段复制”程序,也就是我们说的从加载域到执行域的转换程序; You don't have this with the latter, so if you want to do a segment copy, you have to write your own program to do it, and then you can go into our main function, and it doesn't have to be called main(), it can be called something nice, unlike B __main;后者你没有这个,所以如果你想做段拷贝,你得自己写程序来做,然后你可以go进入我们的主function,也可以不用调用main(),它可以称为好东西,不像B __main; No MATTER WHICH WAY WE USE TO ENTER OUR PROGRAM, there MUST BE A "SECTION COPY" program, RUN THE SECTION COPY AFTER CAN ENTER OUR MAIN PROGRAM, (By the way. startup,s does not have a "segment copy" function, so it's no good looking!)无论我们使用哪种方式进入我们的程序,都必须有一个“SECTION COPY”程序,运行 SECTION COPY AFTER CAN ENTER OUR MAIN PROGRAM,(顺便说一句。startup,s没有“segment copy”功能,所以不好看!)

For programs that contain a launcher," execute at the same address as load "is not easy to implement:对于包含启动器的程序,“在与加载相同的地址执行”并不容易实现:

If the execution address is the same as the load address, of course, you do not need to do a "segment copy ", but I understand that the compiler will also add a" segment copy "program (if B __main is used), just because the condition is not met and not executed;如果执行地址和加载地址相同,当然不需要做“段拷贝”,但我理解编译器也会加一个“段拷贝”程序(如果使用了B__main),只是因为条件不满足而没有执行; However, IT IS NOT EASY TO "EXECUTE AT THE SAME ADDRESS AS LOAD" FOR A PROGRAM CONTAINING A LAUNCHER.但是,对于包含启动器的程序来说,“在与负载相同的地址执行”并不容易。 Because the startup program is to burn into the non-volatile memory, used to execute on the power, and this program will certainly have RW segment, if the RW in the non-volatile memory, such as FLASH, it is not easy to achieve RW function, so RW to move to the memory can achieve RW function, such as SRAM.因为启动程序是烧入非易失的memory,用来上电执行的,而且这个程序肯定会有RW段,如果非易失的memory中的RW,比如Z227B519E823A8B9932DZ9302,就不容易实现7032DZ9302 RW function,所以RW移动到memory可以实现RW function,比如SRAM。 Therefore," execution address and load address are the same "is not easy to implement for programs that contain startup;因此,“执行地址和加载地址相同”对于包含启动的程序来说是不容易实现的; The entry point to the program is at __main in the C library, where the library code does the following:该程序的入口点位于 C 库中的 __main 处,其中库代码执行以下操作:

  1. Copy the non-zero (read and write) run region from its load address to the run address.将非零(读取和写入)运行区域从其加载地址复制到运行地址。

  2. Clear the ZI area.清除 ZI 区域。

  3. Go to __rt_entry. Go 到 __rt_entry。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM