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

64位Linux系统下NASM编译ASM与C程序链接问题咨询

Hey there! Let's figure out what's causing your issue when linking your NASM assembly and C code on 64-bit Linux. As someone learning x86-64 assembly, the problem usually boils down to either code mismatches (like calling conventions or missing declarations) or incorrect compilation/linking commands. Let's walk through both angles.

First: Check Your Code for Common Issues

Assembly File (hello.asm)

For printf to work correctly and for your printHello function to be callable from C, you need to follow the System V AMD64 calling convention (the standard for 64-bit Linux) and export your function properly. Here's a correct example to compare against:

section .data
    hello_msg db "Hello", 0  ; Critical: printf requires null-terminated strings!

section .text
    global printHello        ; Export this function so the C linker can find it
    extern printf            ; Declare that we're using the external printf function

printHello:
    push rbp                 ; Set up a stack frame (optional but good practice)
    mov rbp, rsp
    sub rsp, 16              ; Ensure stack is 16-byte aligned (required before calling libc functions)
    
    mov rdi, hello_msg       ; 1st argument to printf goes in RDI: the string address
    call printf              ; Invoke printf
    
    mov rsp, rbp             ; Clean up the stack frame
    pop rbp
    ret

Common assembly mistakes to look for:

  • Forgetting the null terminator (0) at the end of your string (this will cause printf to print garbage until it hits a random null byte)
  • Not aligning the stack before calling printf (libc functions expect the stack pointer to be a multiple of 16 when called)
  • Putting printf arguments in the wrong registers (System V AMD64 uses RDI, RSI, RDX, RCX, R8, R9 for the first six arguments)
  • Omitting global printHello (the linker won't know your function exists otherwise)

C File (main.c)

You need to declare the assembly function so the C compiler knows its signature. Otherwise, it'll assume a default int return type, which can cause calling errors:

#include <stdio.h>

// Declare the assembly function (extern is optional here but explicit)
void printHello();

int main() {
    printHello();
    return 0;
}

Common C mistake: Missing the void printHello(); declaration.

Second: Verify Your Compilation/Linking Commands

On 64-bit Linux, you need to make sure NASM generates a 64-bit ELF object file, then link it with your C code using GCC (which handles linking against the C standard library automatically).

Correct Step-by-Step Commands

  1. Compile the assembly file into a 64-bit object file:
    nasm -f elf64 hello.asm -o hello.o
    
  2. Compile the C file and link it with the assembly object file:
    gcc main.c hello.o -o hello
    

You can also combine these into one command (though separate steps are easier to debug if something fails):

gcc main.c hello.asm -o hello

Common Command Mistakes

  • Using nasm -f elf32 (generates 32-bit object code, which can't link with 64-bit C code)
  • Trying to link directly with ld instead of GCC: ld won't automatically link the C standard library (which printf depends on). If you insist on using ld, you need to explicitly specify libc and the dynamic linker:
    ld -o hello main.o hello.o -lc -dynamic-linker /lib64/ld-linux-x86-64.so.2
    
  • Forgetting to specify the output object file with -o hello.o (NASM will default to a.out, which might get overwritten or missed by GCC)

If You're Still Stuck

If you run into a specific error message (like linker errors about undefined references, or runtime crashes), share that message! It'll make it much easier to pinpoint exactly what's going wrong.

内容的提问来源于stack exchange,提问作者Benjamin Sx

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 06:57:03