编写求两值最大值的汇编代码编译报错:Undefined reference to main
汇编求最大值编译错误排查与修正
编译错误信息
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/Scrt1.o: in function `_start': (.text+0x20): undefined reference to `main' collect2: error: ld returned 1 exit status
原始汇编代码
bits 64 global my_average section .text start: push rbp mov rbp, rsp xor rax, rax add rax, rdi add rbx, rsi cmp rax , rbx jge .end .end: mov rax, rbx mov rsp, rbp pop rbp ret
错误原因分析
1. 链接阶段找不到main函数
用gcc默认编译链接时,会自动引入标准启动代码,而启动代码要求main作为程序入口。你的代码入口标签是start,且全局符号声明的是my_average,两者不匹配,导致链接器找不到指定入口。
2. 代码逻辑与规范问题
- 全局符号与函数标签不符:声明的
my_average和实际函数标签start不一致,无法正确导出函数。 - 最大值计算逻辑错误:当前代码对
rax、rbx的操作逻辑混乱,没有直接比较输入参数rdi和rsi,且rbx初始值未定义,无法得到正确结果。 - 违规使用寄存器:
rbx属于x86-64系统V调用约定中的调用者保存寄存器,函数内部未经保存直接使用会破坏调用者的数据,且求最大值完全不需要用到该寄存器。
修正后的代码
方案1:作为独立可执行程序(带main入口)
bits 64 global main section .text main: push rbp mov rbp, rsp ; 直接比较前两个参数rdi和rsi,将较大值存入rax返回 mov rax, rdi cmp rax, rsi jge .end ; 若rdi >= rsi,直接跳转至返回逻辑 mov rax, rsi ; 否则将rsi存入rax .end: mov rsp, rbp pop rbp ret
编译命令:gcc -o max_program max.s
方案2:作为可被其他程序调用的函数
bits 64 global max_value ; 全局符号与函数标签保持一致 section .text max_value: push rbp mov rbp, rsp mov rax, rdi cmp rax, rsi jge .end mov rax, rsi .end: mov rsp, rbp pop rbp ret
编译成目标文件:nasm -f elf64 max.s -o max.o
可搭配C代码调用示例:
#include <stdio.h> extern long max_value(long a, long b); int main() { printf("最大值:%ld\n", max_value(45, 23)); return 0; }
编译命令:gcc -o test_max test.c max.o
补充说明
- x86-64系统V调用约定中,函数前两个参数存在
rdi、rsi寄存器,返回值需存入rax。 - 若坚持用
start作为入口,可直接用ld链接并指定入口点:ld -e start max.o -o max,但这种方式会跳过标准启动代码的初始化,仅适合极简程序。
内容的提问来源于stack exchange,提问作者TheTricky65
相关产品推荐
相关产品推荐

