You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

编写求两值最大值的汇编代码编译报错: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 05:45:42