使用gcc编译时在程序集x86-64 nasm中使用用户定义的入口点

使用gcc编译时在程序集x86-64 nasm中使用用户定义的入口点,gcc,assembly,nasm,x86-64,Gcc,Assembly,Nasm,X86 64,我最近开始学习汇编,想知道在使用gcc编译时,是否有可能为汇编代码定义自己的入口点 例如,使用gcc编译的标准代码是 全球主要 第二节数据 第2节bss 第节.案文 主要内容: 我想将入口点更改为一个更明确的名称,如“addition”,如下所示 全局加法 第二节数据 第2节bss 第节.案文 补充: 我之所以首先使用gcc进行编译,是因为我在“printf”和“scanf”的汇编代码中使用c库,每次我试图更改入口点时,都会得到一个未定义的对主错误的引用。如果您是在汇编中编写而不使用c运行时库,

我最近开始学习汇编,想知道在使用gcc编译时,是否有可能为汇编代码定义自己的入口点

例如,使用gcc编译的标准代码是

全球主要

第二节数据

第2节bss

第节.案文

主要内容:

我想将入口点更改为一个更明确的名称,如“addition”,如下所示

全局加法

第二节数据

第2节bss

第节.案文

补充:


我之所以首先使用gcc进行编译,是因为我在“printf”和“scanf”的汇编代码中使用c库,每次我试图更改入口点时,都会得到一个未定义的对主错误的引用。

如果您是在汇编中编写而不使用c运行时库,然后你可以随意调用你的入口点。您可以使用gcc命令行选项
-Wl,-entry=
或链接器脚本中的entry指令告诉链接器入口点的名称。链接器将此入口点的地址写入可执行文件


如果您使用的是C运行时库,那么可执行文件中的入口点必须是C运行时库的入口点,以便它可以执行初始化。该入口点通常称为crt0。当crt0完成初始化时,它调用
main
,因此在本例中,您不能更改名称。

如果您在汇编中编写而不使用C运行时库,则可以调用您的入口点。您可以使用gcc命令行选项
-Wl,-entry=
或链接器脚本中的entry指令告诉链接器入口点的名称。链接器将此入口点的地址写入可执行文件


如果您使用的是C运行时库,那么可执行文件中的入口点必须是C运行时库的入口点,以便它可以执行初始化。该入口点通常称为crt0。当crt0完成初始化时,它调用
main
,因此在这种情况下,您不能更改名称。

您可以在同一地址上放置多个标签。因此,您可以将
main
标签粘贴在您希望CRT启动代码调用
的任何位置

global main
main:
addition:
   lea  eax, [rdi+rdi]    ; return argc*2
   ret
我选中了,GDB选择在反汇编中为标签后面的代码块显示
main
,而不管您首先声明的是哪一个。(`全局加法也没有帮助。)


当然,如果您希望能够更改文件顶部的一行以选择哪个函数是
main
入口点,您可以这样做

%define addition main
我不确定NASM是否允许您为符号创建别名或弱别名,如GAS

.weakref main,addition
。()

您可以在同一地址上放置多个标签。因此,您可以将
main
标签粘贴在您希望CRT启动代码调用
的任何位置

global main
main:
addition:
   lea  eax, [rdi+rdi]    ; return argc*2
   ret
我选中了,GDB选择在反汇编中为标签后面的代码块显示
main
,而不管您首先声明的是哪一个。(`全局加法也没有帮助。)


当然,如果您希望能够更改文件顶部的一行以选择哪个函数是
main
入口点,您可以这样做

%define addition main
我不确定NASM是否允许您为符号创建别名或弱别名,如GAS

.weakref main,addition
。不,你不能那样做。您可以为流程选择入口点,但如果使用C,则它位于调用
main
的C库中,并且无法更改。如果程序执行加法,则将可执行文件命名为加法,而不是函数。或者,创建一个单独的加法函数并从main调用它。谢谢您的回答!我有一个后续问题,如果入口点必须定义为main,那么如果我试图从外部为“c”int main(int)的c文件调用我的汇编代码,即使入口点的名称是main(我认为这可能与int main()的c体冲突),它仍然可以工作吗?它不会工作。您将出现链接器错误,多次定义符号。如果你已经有了一个
main
,那么你可以随意命名你的函数并调用它。编译.c和汇编.asm生成的目标文件是“相等”的,也就是说,如果两个目标文件包含函数“main”,链接器将报告重复性。如果没有任何对象文件包含某些代码所需的符号,它将报告缺少的符号。因此,在C或汇编语言中定义
main
并不重要,但必须只定义一次。通常在C中使用
main
,只在汇编中编写特定的子例程(如
addition
)更简单。不,您不能这样做。您可以为流程选择入口点,但如果使用C,则它位于调用
main
的C库中,并且无法更改。如果程序执行加法,则将可执行文件命名为加法,而不是函数。或者,创建一个单独的加法函数并从main调用它。谢谢您的回答!我有一个后续问题,如果入口点必须定义为main,那么如果我试图从外部为“c”int main(int)的c文件调用我的汇编代码,即使入口点的名称是main(我认为这可能与int main()的c体冲突),它仍然可以工作吗?它不会工作。您将出现链接器错误,多次定义符号。如果你已经有了一个
main
,那么你可以随意命名你的函数并调用它。编译.c和汇编.asm生成的目标文件是“相等”的,也就是说,如果两个目标文件包含函数“main”,链接器将报告重复性。如果没有对象文件包含某些代码要求的符号