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

如何让32位NASM汇编代码在64位架构下正常运行?

Hey there! Let's break down why your code is hitting that Invalid memory reference (SIGSEGV) error and fix it step by step, plus share some solid resources for learning 64-bit NASM.

Why Your 32-bit Code Fails in 64-bit Mode

Your core issue is that 64-bit Linux uses a completely different system calling interface than 32-bit—just swapping eax for rax isn't enough. Here's what's going wrong:

  • System call instruction: 32-bit uses int 0x80, but 64-bit requires syscall.
  • Syscall numbers are different: 32-bit sys_write is 4, but 64-bit is 1; 32-bit sys_exit is 1, 64-bit is 60.
  • Argument registers changed: 64-bit syscalls use rdi, rsi, rdx, r10, r8, r9 for arguments (instead of ebx, ecx, edx), with the syscall number stored in rax.
  • Stack frame corruption: Your original function missed saving rbp to the stack before modifying it, which broke the return address when ret ran—this is the direct cause of your SIGSEGV.

Fixed 64-bit NASM Code

Here's a working version with comments explaining key changes:

; Compile with: nasm -f elf64 hello.asm -o hello.o && ld hello.o -o hello
section .text
global _start
_start:
    call func       ; Call our print helper function
    ; 64-bit sys_exit (syscall number 60)
    mov rax, 60     ; Load exit syscall number into rax
    mov rdi, 0      ; Exit code 0 (success)
    syscall         ; Invoke the kernel

func:
    push rbp        ; Save original base pointer (standard function prologue)
    mov rbp, rsp    ; Set base pointer to current stack top
    sub rsp, 2      ; Allocate 2 bytes of stack space for our "Hi" string
    
    mov byte [rsp], 'H'   ; Store 'H' at the start of our stack buffer
    mov byte [rsp+1], 'i' ; Store 'i' immediately after
    
    ; 64-bit sys_write (syscall number 1)
    mov rax, 1      ; Load write syscall number into rax
    mov rdi, 1      ; File descriptor 1 = stdout
    mov rsi, rsp    ; Pointer to our stack buffer containing "Hi"
    mov rdx, 2      ; Number of bytes to write (2 for 'H' and 'i')
    syscall         ; Invoke the kernel
    
    mov rsp, rbp    ; Restore stack pointer to its original state
    pop rbp         ; Restore the saved base pointer
    ret             ; Return to the _start label

Learning Resources for 64-bit NASM & Registers

  • NASM Official Manual: The official docs have a detailed section on x86-64 syntax, stack handling, and calling conventions. Focus on the "x86-64 Features" chapter to get up to speed on register usage differences from 32-bit.
  • Linux Syscall Reference: Use the man 2 syscall man page to look up 64-bit syscall numbers and their required register arguments. Start with the basics: write, exit, read.
  • Stack Frame Fundamentals: Master the standard function prologue (push rbp; mov rbp, rsp) and epilogue (mov rsp, rbp; pop rbp)—this will eliminate most stack-related crashes like your SIGSEGV.
  • Incremental Practice: Build tiny programs first (print a single character, exit with a code, read a single input byte) before moving to more complex logic. Each small program will help reinforce how 64-bit registers and syscalls work.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:12:19