Linux x86_64下如何编写含main函数的GAS AT&T格式Hello World汇编程序
Linux x86_64汇编实现带标准main函数的程序并通过GCC链接
问题背景
我使用Linux x86_64系统,已实现一个直接使用_start入口的汇编程序,代码如下:
.code64 .section .rodata msg: .ascii "Hello, World!\n" .set msglen, (. - msg) .section .text .global _start _start: mov $1, %rax mov $1, %rdi lea msg, %rsi mov $msglen, %rdx syscall mov $60, %rax mov $0, %rdi syscall
该代码通过as -o hello.o -s hello.s编译、ld -o hello hello.o链接可正常运行。现在希望将程序入口改为标准main函数,使用as main.s -o main.o编译,再通过gcc main.o -o main链接,请问如何实现?
解决方案
1. 修改汇编代码适配main函数入口
需要将入口点从_start改为main,同时遵循C语言的函数调用规范(main函数返回值通过rax寄存器传递,最终由启动代码处理退出逻辑,无需手动调用exit系统调用)。修改后的代码如下:
.code64 .section .rodata msg: .ascii "Hello, World!\n" .set msglen, (. - msg) .section .text .global main # 将入口改为main main: # 执行write系统调用输出字符串 mov $1, %rax # syscall编号:1对应write mov $1, %rdi # 文件描述符:1对应stdout lea msg, %rsi # 字符串地址 mov $msglen, %rdx # 字符串长度 syscall # main函数返回0(符合C规范,返回值存在rax中) mov $0, %rax ret # 返回给C启动代码,由它处理退出
2. 编译与链接命令
- 编译:使用
as汇编器生成目标文件as -o main.o main.s - 链接:使用
gcc进行链接(gcc会自动链接C运行时启动代码,处理main函数的入口逻辑)gcc main.o -o main
说明
- 当使用
gcc链接时,程序的实际入口是C运行时的_start函数,它会调用我们定义的main函数,执行完成后自动处理退出流程,因此无需手动调用exit系统调用。 - 如果需要调用libc中的函数(比如
printf),还需要遵循x86_64的函数调用约定(参数依次存放在rdi、rsi、rdx等寄存器),并确保链接时包含libc库(gcc默认会链接)。
内容的提问来源于stack exchange,提问作者Kode1000
相关产品推荐
相关产品推荐

