如何让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 requiressyscall. - Syscall numbers are different: 32-bit
sys_writeis 4, but 64-bit is 1; 32-bitsys_exitis 1, 64-bit is 60. - Argument registers changed: 64-bit syscalls use
rdi,rsi,rdx,r10,r8,r9for arguments (instead ofebx,ecx,edx), with the syscall number stored inrax. - Stack frame corruption: Your original function missed saving
rbpto the stack before modifying it, which broke the return address whenretran—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 syscallman 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
相关产品推荐
相关产品推荐

